Sign in
TodayMapLearnPracticeReview
Library
15 MINcoreDatabases & Data SystemsNot started

SQL vs NoSQL

SQL databases (PostgreSQL, MySQL) store data in tables with strict schemas and support ACID transactions. NoSQL databases (Cassandra, MongoDB, DynamoDB) trade strict consistency for scalability, flexibility, or performance. The choice depends on your data shape, consistency requirements, and scale.

Why this matters

Choosing the wrong database is one of the most expensive mistakes in system design. Migrating from SQL to NoSQL (or vice versa) after launch is painful and risky. Understanding when to use each — and when to use both — is a core skill.

Prerequisites
  • What is System Design
Related
  • Key-Value Stores
  • Document Stores
  • Replication
  • Sharding
Used in
  • CQRS
  • Data Modeling
  • Denormalization
  • Design Hotel Reservation
  • Design Instagram
  • Document Stores
  • Graph Databases
  • Key-Value Stores
  • Replication
  • SQL Tuning
  • Transactions & ACID
  • Wide Column Stores
Lesson

How it works

The SQL vs NoSQL choice is not about which is 'better' — it's about which trade-offs fit your problem. SQL databases excel at structured data, complex queries, and ACID transactions. NoSQL databases excel at scale, flexible schemas, and specific access patterns.

The key insight: NoSQL is not one thing. It's an umbrella for several different database models — key-value, document, wide-column, graph — each with different trade-offs.

SQL strengths:

  • ACID transactions: multi-operation, all-or-nothing. Critical for payments, inventory, bookings.
  • Structured schema: columns and types are enforced. Prevents bad data.
  • JOINs: query across related tables efficiently.
  • Mature ecosystem: ORMs, tooling, decades of optimization.
  • Consistency: strong (linearizable) by default.

SQL weaknesses:

  • Vertical scaling: hard to shard across machines.
  • Schema changes: migrations are painful at scale.
  • Impedance mismatch: relational model doesn't map cleanly to objects.

NoSQL types:

  • Key-value (Redis, DynamoDB): simplest. Key → value. Extremely fast. No query complexity.
  • Document (MongoDB, CouchDB): key → document (JSON). Flexible schema. Good for content, profiles, catalogs.
  • Wide-column (Cassandra, HBase): rows with dynamic columns. Good for time-series, high-write throughput.
  • Graph (Neo4j): nodes and edges. Good for social networks, recommendation engines, fraud detection.

Each is optimized for a specific access pattern. Choosing the right NoSQL type requires knowing your query patterns.

How to choose
  1. Need ACID transactions (payments, inventory)? → SQL (PostgreSQL).
  2. Need massive write throughput (time-series, logs)? → Wide-column (Cassandra).
  3. Need flexible schema (content, user profiles)? → Document (MongoDB).
  4. Need sub-millisecond reads (cache, counters)? → Key-value (Redis).
  5. Need complex relationships (social graph, recommendations)? → Graph (Neo4j).
  6. Not sure? Start with PostgreSQL. You can migrate later if needed.
Check yourself
core

You're building a payment system that handles credit card charges. Which database should you use?

Pick one answer.

Check yourself
interview

You're building a system that logs 1 billion events per day (time-series data). Which database is best suited?

Pick one answer.

DimensionSQL (PostgreSQL, MySQL)NoSQL (Cassandra, MongoDB, DynamoDB, Redis)
Data modelTables, rows, columns, foreign keysKey-value, document, wide-column, graph — varies by type
SchemaStrict, enforced by DB; migrations are expensiveFlexible / schema-on-read; schema enforced by app
JoinsNative, optimized, ACID across joined tablesLimited or none; denormalize to avoid
TransactionsACID (atomic, consistent, isolated, durable)Often BASE (basically available, soft state, eventual consistency); some support per-partition ACID
ConsistencyStrong (linearizable) by defaultTunable / eventual by default; some offer strong on single partition
Scaling modelVertical primary + read replicas; horizontal via sharding is hardBuilt for horizontal sharding; add nodes and rebalance
Query languageSQL (declarative, standard)DB-specific (CQL, MongoDB Query Language, Redis commands)
Best atComplex queries, multi-row transactions, financial data, structured dataMassive write throughput, flexible schema, single-key lookups, global distribution
Worst atHorizontal scaling beyond a few shards, schema churn, very high write QPSMulti-entity transactions, JOINs, ad-hoc analytics, referential integrity
Maturity40+ years, huge ecosystem, well-understood failure modes15-ish years, smaller ecosystems, more surprises at scale
Default choicePostgreSQL — until you outgrow itOnly when SQL doesn't fit the access pattern
SQL vs NoSQL across the dimensions that actually drive the choice in production.
ACID vs BASE — the philosophical divide

ACID (SQL's promise): Atomic — all-or-nothing transactions. Consistent — DB enforces invariants (foreign keys, constraints). Isolated — concurrent transactions don't see each other's partial writes. Durable — committed writes survive crashes. ACID trades latency and availability for correctness. Use when a half-completed transaction is worse than a failed one (payments, bookings, inventory).

BASE (NoSQL's promise): Basically Available — system remains responsive under failure. Soft State — application reconciles state over time. Eventually Consistent — replicas converge given enough time. BASE trades correctness for availability and partition tolerance. Use when stale data is acceptable (social feeds, dashboards, logs).

The two are not 'right vs wrong' — they're different points on the CAP trade-off curve. Most real systems use both: SQL for transactional core (payments, users, inventory) and NoSQL for the read-heavy / write-heavy periphery (feeds, analytics, cache).

System design foundations and networking context— Supplementary explanation. The NO CAP lesson remains self-contained.

Real example: Uber's polyglot persistence.

Uber's stack uses different databases for different access patterns (documented across years of engineering blog posts):

  • Schemaless on MySQL for trips, users, drivers — sharded by UUID, high-write-throughput, eventually consistent across regions. Custom store they built because no off-the-shelf DB fit their write profile + global consistency needs.
  • PostgreSQL for billing and financial data — ACID transactions, foreign keys, auditable. Worth the cost of a stricter scaling story because the cost of a double-charge or lost-charge is so high.
  • Cassandra for location tracking (driver positions updated every few seconds per driver; hundreds of thousands of writes/sec; reads are 'where are drivers near this rider'). Massive write throughput, time-series friendly.
  • Redis for caching (hot trip state, rate-limit counters, session data). Sub-millisecond reads, in-memory, accepts data loss on crash for the cache use case.
  • Elasticsearch for full-text search (rider destination autocomplete, driver destination search). Inverted-index optimized for relevance-ranked text queries.
  • Kafka for event streaming (every trip event flows through Kafka; downstream consumers derive analytics, billing, fraud signals).

Why so many? Because each access pattern has a different optimal storage primitive. Trying to do all of this in one database means either (a) the financial data loses ACID guarantees (dangerous) or (b) the location tracking can't keep up with writes (system failure). Polyglot persistence — using different databases for different access patterns — is the standard pattern at scale. The cost: more infrastructure to operate, more schemas to keep in sync, more failure modes to understand. The rule of thumb: don't introduce a new database until the cost of operating it is less than the cost of forcing your existing DB to do something it's bad at.

Check yourself
interview

You're designing the data layer for a ride-sharing app. Which of these database assignments is the strongest argument for polyglot persistence?

Pick one answer.

PostgreSQL jsonb — the bridge that often eliminates the need for NoSQL.

A common architectural mistake is choosing MongoDB for 'flexible schema' when PostgreSQL has had jsonb (binary JSON) since 9.4 (2015). jsonb stores arbitrary JSON in a binary format, supports indexing via GIN indexes, and lets you query nested fields with SQL operators. The result: many workloads that 'need NoSQL' actually just need flexible schema in a single table — and PostgreSQL can do that without giving up ACID, JOINs, or transactions.

Example schema that bridges the gap:

code
CREATE TABLE events (
  id          BIGSERIAL PRIMARY KEY,
  user_id     BIGINT NOT NULL,
  event_type  TEXT   NOT NULL,
  payload     JSONB  NOT NULL,  -- flexible per-type schema
  created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Index the JSON for fast lookups
CREATE INDEX idx_events_payload ON events USING GIN (payload jsonb_path_ops);
-- Index user_id + created_at for time-range queries
CREATE INDEX idx_events_user_time ON events (user_id, created_at DESC);

Now you can query with both structured (SQL) and document (JSON) operations:

code
-- Find login events for user 42 in the last hour with browser=Chrome
SELECT * FROM events
  WHERE user_id = 42
    AND event_type = 'login'
    AND created_at > NOW() - INTERVAL '1 hour'
    AND payload->>'browser' = 'Chrome';

When does this NOT suffice, and you really do need NoSQL?

  • Write throughput beyond ~50K writes/sec on a single primary — Cassandra or DynamoDB scale horizontally where PostgreSQL can't.
  • NoSQL-style horizontal sharding is core — Cassandra, DynamoDB, and MongoDB shard transparently; PostgreSQL sharding (Citus) is good but adds operational complexity.
  • Schema is truly schemaless and evolves per record — e.g., user-generated forms. Document stores handle this natively; SQL requires the jsonb escape hatch.

The decision rule: reach for PostgreSQL + jsonb first. Switch to a document store only when you've proven the jsonb path can't meet your write throughput or scaling needs. The cost of being wrong in this direction is small (a migration); the cost of starting with NoSQL and realizing you needed ACID is much larger.

Engineering mental model

Mental model. Think of SQL vs NoSQL as a deliberate boundary in a system. The boundary exists because something becomes harder to manage when everything is done in one place: latency, scale, failure isolation, consistency, cost, or team ownership. The useful question is not “what does SQL vs NoSQL mean?” but “what pressure makes this boundary worth introducing, and what new failure mode does it create?”

Design lens

Before choosing SQL vs NoSQL, name the workload, the critical user path, the dominant bottleneck, the failure you are trying to absorb, and the trade-off you are willing to accept. If you cannot name those five things, the design is probably premature.

Original NO CAP systems visual for SQL vs NoSQL.
Image unavailable. Original NO CAP systems visual for SQL vs NoSQL.
SQL vs NoSQL: a compact system-thinking visual.— Original NO CAP visual.
SELECT id, created_at
FROM records
WHERE tenant_id = ?
ORDER BY created_at DESC
LIMIT 50;

-- Ask: which index makes this query predictable at scale?
A minimal engineering sketch for reasoning about SQL vs NoSQL.

Back-of-the-envelope reasoning

Numerical lens: write down traffic, payload size, read/write ratio, peak multiplier and durability target before choosing a component. The numbers should justify the architecture.

Interactive sandboxdeterministic

Interactive thought experiment: SQL vs NoSQL

Change the variables below and predict what breaks first in SQL vs NoSQL. The production lab can later reuse these same inputs.

System pressure6%
Try this

Change one variable at a time. Predict the failure mode first, then move the slider and see whether your mental model matches the simplified system response.

Hint

If you are stuck on SQL vs NoSQL, start by drawing the request path and marking every network hop, stateful component, queue, cache and failure boundary. Then estimate where the system will saturate.

Check yourself
solid

You increase traffic by 10× in a system using SQL vs NoSQL. What should you inspect first?

Pick one answer.

Check yourself
interview

Which statement is the safest engineering habit when using SQL vs NoSQL?

Pick one answer.

Try this
interview

You have dashboards for traffic, latency, errors and saturation. You can change the architecture, but every change has operational cost.

Production scenario: your system uses SQL vs NoSQL, traffic suddenly spikes, and p99 latency doubles. What is your first move?

Interview drill

Answer this without notes: When would you choose SQL vs NoSQL, and when would you intentionally avoid it? Mention at least one bottleneck it addresses, one failure mode it introduces, and one alternative. Then quantify the workload you are designing for.

Engineering lens

For SQL vs NoSQL, start with access patterns rather than brand names. Identify the dominant reads/writes, data relationships, consistency requirements, partition key, hot keys and failure behavior before choosing a storage strategy.

Numerical sanity check

A rough capacity check: required write throughput ≈ peak writes/s × average record size. At 5,000 writes/s and 2 KB average payloads, the raw incoming data stream is about 10 MB/s before indexes, replication and overhead.

Check yourself
interview

Do not optimize for a memorized definition. Reason from the workload and failure mode.

A team proposes SQL vs NoSQL because it 'scales'. What workload characteristic would make that choice a poor fit?

Pick one answer.

Trade-offs

What you gain, what you pay

Pros
  • +SQL: ACID, JOINs, mature ecosystem, strong consistency.
  • +NoSQL: horizontal scalability, flexible schema, high throughput for specific patterns.
  • +NoSQL: each type is optimized for a specific use case (KV=speed, document=flexibility, wide-column=throughput, graph=relationships).
Cons
  • −SQL: hard to shard, schema migrations are painful, vertical scaling ceiling.
  • −NoSQL: eventual consistency (usually), no JOINs (must denormalize), less mature tooling.
  • −NoSQL: each type is a specialist — wrong choice = bad performance.
Failure modes

How this breaks in production

  • Using NoSQL for transactional data — loses ACID guarantees.
  • Using SQL for massive write throughput — can't scale writes without sharding.
  • Choosing a NoSQL type without understanding query patterns — e.g., using MongoDB for graph queries.
  • Polyglot persistence without clear boundaries — too many databases to maintain.
Common mistakes

Don't fall into these traps

  • •Treating 'NoSQL' as one thing — it's 4 different models with different trade-offs.
  • •Choosing NoSQL for 'scalability' without understanding your consistency needs.
  • •Using SQL when your data is naturally a graph — SQL JOINs for graph queries are slow.
  • •Forgetting that PostgreSQL can handle JSON (jsonb) — you might not need MongoDB.
Where you see it

Real systems using this

Almost every production system uses at least one SQL or NoSQL database.Large systems use both: SQL for transactional data, NoSQL for specific access patterns.
Teardowns

How real systems implement this

  • Uber — Uses Schemaless (built on MySQL) for most data, Redis for caching, and Cassandra for location tracking. Polyglot persistence.
  • Netflix — Uses Cassandra for viewing history (massive writes), EVCache (Redis) for caching, and MySQL for billing (ACID required).
Interview prompts

Practice saying it out loud

  • Q1When would you choose SQL over NoSQL?
  • Q2What are the different types of NoSQL databases?
  • Q3Can you use both SQL and NoSQL in the same system? When?
Research

Further reading & references

System Design Primer
Open source
ByteByteGo — Scale from zero to millions
ByteByteGo
System Design Tutorial
GeeksforGeeks
System Design Roadmap
roadmap.sh
Databases & Data Systems reference
Reference
Databases & Data Systems reference
Reference
Databases & Data Systems reference
Reference

Core explanations are original NO CAP material. External references are provided for deeper study and standards.

What next?

Mark as understood once the mental model clicks.

Next recommended

Key-Value Stores