Handbooks  /  SQL vs NoSQL
Engineering~9 min readComparison
Head to Head

SQL vs NoSQL: structure, or scale?

SQLvsNoSQL

This debate is framed as a war, but it’s really a menu. SQL (relational) databases give you a fixed schema, joins across tables, and strong ACID guarantees — brilliant when your data is related and correctness matters. NoSQL is an umbrella for stores that drop some of that to buy flexible schemas and easy horizontal scale. The right pick is decided by how you read and write, not by fashion.

01

The core difference: relationships vs scale

SQL databases (Postgres, MySQL…) store data in tables with a defined schema and let you join across them, with ACID transactions guaranteeing correctness even under concurrency. They’re the right default when your data is relational and you value consistency. NoSQL isn’t one thing — it’s document (MongoDB), key-value (DynamoDB, Redis), wide-column (Cassandra), and graph (Neo4j) stores that each drop some relational feature (usually joins and strict schema) to gain horizontal scale and flexibility.

→ The rule

Data with lots of relationships, and correctness you can’t compromise (money, inventory, users)? SQL. A specific access pattern at massive scale where you rarely join — huge write volume, flexible/varying documents, or a key-value lookup? A NoSQL store shaped to that pattern.

02

Head to head

DimensionSQL (relational)NoSQL
SchemaFixed, enforcedFlexible / schema-on-read
JoinsYes — the core strengthUsually none; denormalize instead
TransactionsStrong ACIDOften eventual (BASE); varies by store
ScalingVertical first; harder horizontalHorizontal by design
QuerySQL — expressive, ad-hocPer-store APIs; optimized for known patterns
Data shapeRows/columns, normalizedDocuments, key-value, columns, graphs
Best fitRelated data, correctness, ad-hoc queriesScale, flexible/varying data, known patterns

NoSQL’s scale often comes from relaxing consistency — the CAP theorem in action: under a network partition you can’t have both perfect consistency and availability, and many NoSQL stores choose availability with eventual consistency.

03

When to use each

Reach for SQL

  • Related entities (users, orders, payments)
  • Transactions that must be correct (money)
  • Ad-hoc queries and reporting you can’t predict
  • Moderate scale where one strong DB suffices
  • You want one flexible query language

Reach for NoSQL

  • Massive write/read volume beyond one node
  • Flexible or rapidly-changing document shapes
  • A known, simple access pattern (key lookup)
  • Time-series, logs, sessions, caches, feeds
  • Graph traversals (use a graph DB specifically)
→ Start relational

For most applications, start with a relational database (Postgres is the workhorse). It’s flexible, correct, and modern versions scale further than people expect — even adding JSON columns for semi-structured data. Reach for a NoSQL store when a specific, measured scale or access-pattern need appears that SQL genuinely can’t serve. Many systems end up polyglot: SQL for core data, a NoSQL store for the one workload it fits.

04

Why NoSQL scales horizontally when SQL struggles to

The scaling gap isn't arbitrary — it's a direct consequence of what each model promises. A relational database's core value proposition is that any query can join any tables and get a correct answer right now, which means related rows effectively need to be reachable from wherever the query runs. Sharding a relational database across many machines breaks that promise the moment a join needs rows that live on different shards — you either forbid cross-shard joins (giving up a core relational feature) or pay a real latency and complexity cost to fetch and merge across the network.

Most NoSQL stores sidestep this by design: a key-value store or a document store is built around the assumption that a single lookup (by key, or by document ID) is the dominant access pattern, and it never promised you arbitrary joins in the first place. That lets it partition data across many nodes by key with no join to break — each shard is independently correct and complete for the queries the store actually supports. The "cost" isn't scale, it's expressiveness: you paid for horizontal scale by giving up the ability to ask questions the schema didn't anticipate, which is exactly why denormalizing (duplicating related data into the document you'll actually query, instead of normalizing it into a separate joined table) is the standard NoSQL modeling technique — you shape the data around the query, not the query around the data.

→ The trade you're actually making

SQL's joins let you ask questions you didn't anticipate at design time, at the cost of harder horizontal scaling. NoSQL's denormalized-by-key model scales horizontally with ease, at the cost of needing to know your access patterns before you shape the data.

05

A worked scenario: modeling a social app's "who liked this post" feature

Say you're building a social app and need to answer two questions fast: "who liked this post" (for the like-count and avatar row under a post) and "what has this user liked recently" (for their profile). This is a genuinely useful test case because the two questions pull in different directions.

In a relational (SQL) model, this is a likes join table with post_id and user_id columns, indexed on both. "Who liked this post" is SELECT user_id FROM likes WHERE post_id = ?; "what has this user liked" is the same table filtered by user_id instead. One table, two indexes, both questions answered correctly and consistently — and if you later need a third question ("mutual likes between two users"), it's a join away, not a redesign.

In a document (NoSQL) model like MongoDB, you'd typically pick which direction to denormalize for: embed a likedBy array of user IDs directly in the post document (fast "who liked this post," since it's one document read), and separately maintain a likedPosts array on the user document for the reverse query — now the data is duplicated across two documents, and every like requires updating both, with no transaction spanning them by default in many document stores' simplest mode. You've traded a single well-indexed join table for two documents you must keep manually in sync, in exchange for each individual read being a fast, single-document fetch with no join at all.

→ The pattern generalizes

Whenever you need to answer the SAME relationship from BOTH directions equally often, a relational join table with two indexes is often simpler than maintaining two denormalized, manually-synced copies. NoSQL's denormalization shines when there's one dominant, known access pattern you're optimizing hard for — not when you genuinely need symmetric bidirectional queries.

06

Common mistakes

MistakeWhy it bites
Choosing NoSQL for "scale" before hitting any real scale limitA well-indexed Postgres instance comfortably serves far more traffic than most applications ever reach, and starting with SQL keeps ad-hoc queries and joins available for the questions you didn't anticipate — premature NoSQL adoption trades that flexibility away for a scale benefit you may never need.
Expecting NoSQL "eventual consistency" to mean "eventually, in milliseconds"Depending on the store and configuration, "eventual" can mean seconds under normal conditions and longer during a partition or heavy write load — code that reads its own just-written data immediately (a common pattern) can get stale results unless the store offers (and you use) a stronger read option.
Modeling a document store exactly like a relational schema, just without joinsSplitting data into many small, cross-referenced documents the way you'd normalize SQL tables loses the actual benefit of a document store (one read gets everything you need) and keeps the actual cost (no joins to stitch it back together) — document modeling wants deliberate denormalization around your query pattern, not a normalized schema minus joins.
Running ad-hoc analytics queries against a NoSQL store built for one access patternA key-value or document store optimized for "fetch by ID" often has no efficient path for "aggregate across all records matching this arbitrary condition" — the query either scans everything (slow at scale) or simply isn't supported, which is exactly the ad-hoc-query strength SQL was chosen against.
Your call

Which would you pick?

Three situations. Pick the side you'd actually build — the explanation follows.

A new product, moderate traffic, and a team that cannot yet predict which questions the data will need to answer.

A single access pattern — look up an item by key — at enormous volume, with no ad-hoc querying required.

A team justifies NoSQL with "it scales better."

Frequently asked

Quick answers

What is the difference between SQL and NoSQL?

SQL (relational) databases use a fixed schema with tables you can join, and strong ACID transactions — ideal for related data and correctness. NoSQL is an umbrella for document, key-value, wide-column and graph stores that trade joins and strict schema for flexible data models and easy horizontal scaling.

When should I use NoSQL instead of SQL?

When you have a specific access pattern at a scale beyond one node, flexible or rapidly-changing document shapes, or a simple key-value lookup — and you rarely need joins or ad-hoc queries. Time-series, logs, sessions, feeds and caches are common fits, each matched to the right kind of NoSQL store.

Is NoSQL faster than SQL?

For its target access pattern at scale, a NoSQL store tuned to that pattern can be faster and scale more easily. But for related data and ad-hoc queries, a relational database is usually faster and far more flexible. "Faster" depends entirely on the workload — neither is universally quicker.

Which should I choose for a new project?

Start with a relational database like Postgres unless you have a concrete reason not to — it is flexible, correct, handles semi-structured data via JSON columns, and scales further than most projects ever need. Adopt NoSQL when a specific, measured scale or pattern need appears that SQL can’t serve well.

▶  Watch it explained

SQL vs NoSQL: how to actually choose

SQL vs NoSQL · Engineering · Vibe Engines · 2026
Finished this one? 0 / 208 Handbooks done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More Handbooks