Journal — August 5, 2025 · 4 min read

Postgres vs MongoDB — Which Should Your SaaS Actually Use?

A practical comparison of Postgres and MongoDB for SaaS products — schema, queries, scaling, and cost — with a clear default and the specific cases where the default flips.

Every few months I get the same question from a founder: "should we use Postgres or MongoDB?" And nearly every time, the honest answer is Postgres — but the reasoning matters more than the verdict, because there is a real set of cases where it flips.

Here's how I actually decide.

The default: Postgres

Start with Postgres unless you have a specific reason not to. Not because document databases are bad, but because most SaaS products turn out to be relational whether or not you planned for that.

You start with users. Then users belong to organizations. Then organizations have subscriptions, and subscriptions have invoices, and invoices have line items, and someone in sales asks "how much revenue came from teams that signed up in Q2 and are still active?"

That question is a join. It is always a join. In Postgres it's ten lines of SQL. In MongoDB you either denormalize aggressively and maintain consistency by hand, or you reach for $lookup and discover it doesn't behave like a real join at scale.

The second reason is constraints. A foreign key that refuses to let you delete an organization with active subscriptions is a bug that never happens. A CHECK constraint on a status column is a class of bad data that never reaches production. Every constraint you push into the database is application code you don't write and don't test.

Where MongoDB genuinely wins

I want to be fair here, because "just use Postgres" is lazy advice when the shape of your data actually is documents.

Genuinely variable schemas. If you're storing third-party API responses, IoT payloads, or user-defined form submissions where every record has a different shape and you don't control it, documents are the honest model. Yes, Postgres has JSONB, and it's excellent. But if most of your rows are a blob, you're using Postgres as a document store with extra steps.

Write-heavy, read-simple workloads. Event logs, activity feeds, telemetry — high insert volume, queries that fetch by a single key or a time range, no joins. MongoDB's sharding story is more mature and less operationally painful than partitioning Postgres yourself.

Deeply nested data you always read whole. A CMS where a page document contains its blocks, and you never query "all blocks of type X across all pages." Reading one document beats reconstructing a tree from five tables.

If none of those describe you, the document model is buying you flexibility you'll pay for later.

The schema flexibility trap

The pitch for MongoDB is "no migrations, just add a field." This is true and it is a trap.

The schema doesn't disappear when you stop declaring it. It moves into your application code, undocumented, enforced nowhere. Six months in you have records written by four versions of your app. Some have plan, some have planId, some have subscription.plan. Nobody knows which. Every read path grows a defensive ?? chain.

You didn't avoid the migration. You deferred it, and made it worse, because now you have to write a script that handles every historical shape instead of one ALTER TABLE.

Postgres migrations are genuinely annoying for the first week. They're a gift by month six.

What actually decides it in practice

Honestly? The thing that settles most of these arguments isn't technical.

What does your team know? A team fluent in Mongo shipping on Mongo beats the same team fumbling Postgres for a quarter. Velocity is a real constraint, not a cop-out.

What does your hosting look like? Managed Postgres is everywhere and cheap — Supabase, Neon, RDS, Fly. Atlas is good but pricing gets steep as you grow, and self-hosting a Mongo replica set is more operational work than self-hosting Postgres.

Do you need transactions across documents? Mongo has multi-document transactions now, but they carry performance caveats and the ergonomics aren't as clean. If you're moving money, that matters.

The answer I actually give

Building a normal SaaS — users, teams, billing, some domain objects, a dashboard? Postgres. Use JSONB for the genuinely unstructured 10% and enjoy having both models in one database.

Building an analytics pipeline, event store, or content system with wildly variable documents? MongoDB is a reasonable, defensible choice — pick it deliberately rather than by default.

Not sure? Postgres. It's the choice you can grow out of gracefully. Adding a document column to a relational database is a Tuesday. Adding joins to a document database is a rewrite.

The thing nobody tells you

You will probably end up with both. Postgres for the transactional core, something else for search, cache, or analytics. That's normal and fine.

What you want to avoid is the version where your primary store is the wrong shape for your primary access pattern. That's the mistake that costs a quarter to unwind, and it's almost always the one where someone picked a document store for data that turned out to be a graph of relationships wearing a trench coat.

Pick the boring one. Save the interesting decisions for the parts of the product that are actually novel.