Reference · gazar.dev ← All cheat sheets

System design · SQL vs NoSQL

PostgreSQL vs MongoDB.

The two most-argued-about databases, side by side. How they store data, how each handles ACID, what only one of them can do, when to choose which, and the SQL-vs-NoSQL interview questions with answers. Companion to S4 · Data at Scale and the data stores cheat sheet.

01

The core difference: two data shapes

Same order, stored two ways. Postgres normalizes: each fact in one place, across tables, joined at read time. Mongo embeds: store the whole aggregate you read together as one document.

PostgreSQLnormalized · tables
customers
id · email · name
orders
id · customer_id · total · placed_at
order_items
order_id · product · qty

Read an order: JOIN three tables. Change a customer’s email once, everywhere sees it. The database enforces “no order without a customer.”

MongoDBembedded · one document
{
  "_id": "order_42",
  "customer": { "id": "u7", "email": "a@b.com" },
  "items": [
    { "product": "Pen", "qty": 2 },
    { "product": "Pad", "qty": 1 }
  ],
  "total": 1299
}

Read an order: one fetch, no joins. But the customer’s email is copied into every order, so changing it means touching many documents.

The whole trade in one line

Normalizing keeps one source of truth and pays a join on every read. Embedding makes reads one round trip and pays a fan-out write (and possible drift) when shared data changes. Choose by which you do more of.

02

Side by side

The same dimensions, two answers. No row is “better,” each is a different bet.

DimensionPostgreSQLMongoDB
Data modeltables & rows, normalizedBSON documents, often embedded
Schemaenforced (DDL, migrations)flexible (app-enforced)
Joinsnative, any direction$lookup, limited; embed instead
Transactionsfull ACID, multi-row, defaultmulti-doc since 4.0, costlier
Query languageSQLMQL + aggregation pipeline
InvariantsFK, unique, check, for youin-document only, no cross-doc FK
Ad-hoc queriesanything, unplannedbest on planned access patterns
Scale writesvertical, then Citus / partitionsharding built in
Scale readsread replicasreplica-set secondaries
Consistencystrong (single primary)tunable (read / write concern)
Best fitinvariants, relationships, ad-hocaggregate reads, evolving shape, scale

Postgres’ JSONB narrows the gap: it can store documents inside a relational table. It is not a document database, but it means “I might want documents” is rarely a reason to leave Postgres on its own.

03

ACID in both

Postgres gives you ACID by default. MongoDB can give you most of it too, you just opt in, and you model for it.

GuaranteePostgreSQLMongoDB
AtomicityBEGINCOMMIT, all-or-nothing across rowsa single document is always atomic; multi-document via transactions (4.0+)
Consistencyforeign keys, unique & check constraintsschema validation ($jsonSchema); no cross-document foreign keys
IsolationMVCC, up to serializablesnapshot isolation inside a transaction
Durabilitywrite-ahead log + fsyncwrite concern w:"majority", j:true for the journal

The MongoDB move: make the transaction fit in one document

Single-document writes are atomic with zero ceremony, that is the original NoSQL guarantee. So if you embed the things that must change together into one document, you get atomicity for free. Reach for multi-document transactions sparingly; for durability add w:"majority". And the honest tell: if you need multi-document transactions everywhere, your data probably wanted a relational model.

What Postgres still does that Mongo cannot

Enforce an invariant across entities for you, for example “every order row points at a real customer” or “this email is unique across the whole dataset.” In Mongo that rule lives in your application code, and a bug there lets bad data in. That is the real meaning of “Postgres protects the invariant.”

04

What only one of them can do

The capabilities that actually decide it. Pick the side whose list you cannot live without.

Postgres can, Mongo can’t (easily)

  • Multi-table joins and ad-hoc queries you never planned for.
  • Foreign keys enforced by the database across tables.
  • Cross-row invariants: unique across the dataset, check constraints, atomic multi-row updates by default.
  • Window functions, CTEs, and rich SQL analytics.
  • Extensions: PostGIS (geo), pgvector (embeddings), full-text search.
  • Serializable isolation across many rows, cheaply.

Mongo can, Postgres finds awkward

  • One round trip for a deeply nested aggregate, no joins to assemble it.
  • Per-document flexible schema: evolve the shape with no migration.
  • First-class horizontal sharding as a built-in, easy feature.
  • Aggregation pipeline for document-shaped transforms.
  • Fast iteration when the data shape is still moving week to week.

Caveat: Postgres JSONB closes much of this gap (documents, flexible fields, GIN indexes). Sharding and effortless schema-drift are the parts it truly cannot match.

05

When to choose which

Answer what you need, and the choice falls out. When unsure, the safe default is Postgres; earn the exit.

If you need…ChooseWhy
Strong invariants / transactions across entitiesPostgreSQLit enforces them for you
Ad-hoc queries you can’t predictPostgreSQLjoins + SQL, no pre-modeling
Relationships are the pointPostgreSQLjoins, foreign keys
You read one aggregate as a unitMongoDBone document, one read
The schema is still moving fastMongoDBno migration to change shape
Easy built-in horizontal shardingMongoDBsharding is first-class
You’re not sure yetPostgreSQLthe boring, correct default

Default to Postgres when…

You have money, orders, users, or anything with rules that must hold; you can’t predict every query; relationships matter; or you just don’t know the shape yet. It carries you far further than people expect, and JSONB covers most “but I want documents” cases.

Reach for Mongo when…

A screen always loads one self-contained aggregate (a product, a user profile, an event); the shape changes constantly; cross-entity invariants are weak; and you want sharding to be a checkbox, not a project. Then the document model is a genuine fit, not a shortcut.

06

SQL vs NoSQL: interview Q&A

The questions that actually come up, with the short answer and the senior nuance that scores the point. Click to expand.

QWhat is the difference between SQL and NoSQL?+
SQL means relational: a fixed schema, tables with joins, strong ACID, scales vertically first. NoSQL is an umbrella (document, key-value, wide-column, graph) with flexible schema, horizontal scaling, and often tunable or eventual consistency. Senior nuance: reframe it. “It is not SQL vs NoSQL, it is matching the data model to the access pattern. Most NoSQL stores trade joins and cross-entity invariants for scale and shape-flexibility.”
QIs NoSQL faster than SQL?+
Not inherently. NoSQL is faster for the access pattern it was designed around, a single-key or single-aggregate read avoids joins. For ad-hoc or relational queries, SQL usually wins. “Faster” is meaningless without naming the query shape. Senior nuance: “Mongo reads one document in one hop; Postgres joins. If my read is one aggregate, Mongo is faster; if it is ‘all orders over 100 dollars last week grouped by region,’ Postgres is.”
QDoes MongoDB support transactions and ACID?+
Yes. A single-document write has always been atomic. Multi-document ACID transactions arrived in 4.0 (replica sets) and 4.2 (sharded clusters), via sessions. For durability you set the write concern (w:"majority", j:true). Senior nuance: “The idiomatic move is to embed what changes together into one document so you never need a multi-document transaction. If you need them everywhere, the data wanted a relational model.”
QHow do you do a join in MongoDB?+
Three options: $lookup in the aggregation pipeline (a left outer join), embed the related data so no join is needed, or join app-side in code. Joins are not Mongo’s strength; you model around the read. Senior nuance: “If I find myself reaching for $lookup on every query, that is a signal the data is relational and I picked the wrong store.”
QWhen would you NOT use NoSQL?+
When you have strong cross-entity invariants (money, inventory), need ad-hoc queries you cannot predict, or relationships are central. Reaching for Mongo or Cassandra to “scale” at ten thousand rows is résumé-driven, not a real requirement. Senior nuance: “Most teams that think they have outgrown Postgres have a Postgres they never tuned, no replicas, no cache, no indexes.”
QCan you scale SQL horizontally?+
Yes, but it is bolt-on (Citus, Vitess, manual sharding) and you lose easy cross-shard joins and transactions. Mongo, Cassandra and DynamoDB ship sharding as a first-class feature. That said, vertical scaling plus read replicas plus a cache takes Postgres a very long way before you ever shard. Senior nuance: “The shard key is a one-way door in either store, so I delay it and climb the cheaper rungs first.”
QIs MongoDB really “schema-less”?+
No. It is flexible schema, not no schema. The schema moves from the database into your application code. You still design around how the data is read, and you can enforce a shape with $jsonSchema validation. Senior nuance: “Schema-less just means the database stops catching your mistakes, so the discipline has to live in code and review instead.”
QHow do you model one-to-many in each?+
Postgres: a child table with a foreign key back to the parent (an order has many order_items). Mongo: embed the children in the parent document if you always read them together, or reference them by id if they are shared or change independently. Senior nuance: “Embed vs reference is the whole skill in Mongo: embed for read-together aggregates, reference for shared or unbounded data so a document doesn’t grow without limit.”
QWhat is eventual consistency, and does Postgres have it?+
A replica can briefly lag the primary, so a read might not see the latest write. Mongo lets you tune it per operation (read and write concern). Postgres has it too the moment you read from a replica instead of the primary. Senior nuance: “Name read-your-writes: serve a user’s own recent writes from the primary, everything else from replicas. Both databases need this.”

Companion to S4 · Data at Scale and the data stores cheat sheet. Further reading: Postgres transactions · MongoDB transactions · MongoDB data modeling · Postgres JSONB.