CMD Guide
HomeSystem DesignSystem Design Trade-offs

ACID vs BASE Properties in Databases

ACID is not a switch you flip; it is the observable behavior of two engine mechanisms grinding away underneath every transaction — a write-ahead log (WAL) that durably records what a transaction intends to change before that change touches the real data pages, and multi-version concurrency control (MVCC) that hands each transaction its own consistent snapshot so concurrent readers and writers neither block nor corrupt one another.

Everything people call "ACID" falls out of those two mechanisms. BASE (Basically Available, Soft state, Eventually consistent) is the design you reach for when you deliberately give up the single-copy-always-correct guarantee — usually to keep serving during network partitions and to spread writes across many machines. They are not a binary; they are the two ends of a spectrum of how much correctness you trade for availability and scale. The rest of this page shows how ACID is actually implemented, then where BASE and the modern middle ground fit.

The four properties, stated precisely

We will trace one running example: transfer $100 from A to B, where A starts at $500 and B at $100 (total $600).

diagram
diagram

How atomicity and durability actually work: the write-ahead rule

One rule buys both properties: the log record describing a change must reach durable storage before the modified data page does, and a transaction is not "committed" until its COMMIT record is fsync'd. The data pages themselves can stay dirty in memory and get flushed minutes later — the log is the source of truth. Trace the transfer:

  1. Append #10 BEGIN T1 to the log buffer.
  2. Append #11 A: 500→400 (old value and new value — old value enables undo, new value enables redo).
  3. Append #12 B: 100→200.
  4. Append #13 COMMIT and fsync the log up to #13. Only now does the client hear "success."

After a crash, recovery (the ARIES scheme: analyze → redo → undo) scans the log. If #13 made it to disk, it redoes #11 and #12 even if the data pages were never written — durability. If #13 did not, T1 is undone using the old values — atomicity. The single fsync at commit is why durability costs latency; databases amortize it with group commit (batching many transactions' commit records into one fsync).

How isolation actually works: MVCC and isolation levels

Under MVCC, an UPDATE does not overwrite a row — it writes a new version, tagged with the transaction id that created it (xmin) and, on the old version, the id that superseded it (xmax). Each transaction reads against a snapshot: it sees only versions committed as of its start point. So a reader never waits for a writer and a writer never waits for a reader — the classic "readers don't block writers" behavior. Old versions live until no snapshot needs them, then a background collector (Postgres VACUUM) reclaims them.

Perfect isolation (serializable) is expensive, so engines expose weaker levels, each admitting specific anomalies:

Isolation levelDirty readNon-repeatable readPhantom
Read Uncommittedpossiblepossiblepossible
Read Committedpreventedpossiblepossible
Repeatable Readpreventedpreventedpossible*
Serializablepreventedpreventedprevented

*The SQL standard allows phantoms at Repeatable Read; PostgreSQL's Repeatable Read is actually snapshot isolation and blocks phantoms too — but still permits write skew. Defaults differ and this bites people: PostgreSQL, Oracle and SQL Server default to Read Committed; MySQL/InnoDB defaults to Repeatable Read. Guaranteeing a cross-row invariant like "total stays $600" requires Serializable (or explicit locking) — a plain snapshot is not enough.

diagram
diagram

What is BASE?

BASE describes systems — mostly Dynamo-style distributed stores — that keep serving even when nodes can't all talk to each other, by relaxing when copies must agree.

The machinery here is replication, not logging: writes go to several replicas, reads gather from several, and the system uses quorums (serve the read when enough replicas answer), read repair, hinted handoff, and conflict resolution (last-write-wins, vector clocks, or CRDTs) to converge. Many stores let you dial this per operation via tunable consistency: if reads + writes overlap on a majority (R + W > N), you get read-your-writes even on an eventually-consistent engine, at the cost of latency.

The CAP trade-off, stated correctly

CAP is routinely mangled as "pick two of three." The accurate statement: when a network partition happens (and it will — P is not optional), a distributed system must choose, for that partition, between staying Consistent (linearizable) and staying Available. It cannot be both while the partition lasts. When there is no partition, a system can be both C and A — CAP forces a choice only during the split. So the real design axis is CP vs AP, and P is a fact of life, not a menu item.

Two clarifications a senior engineer keeps straight. First, the C in CAP (linearizability across nodes) is not the C in ACID (invariant preservation) — a single-node ACID database trivially has ACID-C but says nothing about CAP. Second, CAP only speaks about partitions; PACELC completes it: else (no partition), you still trade latency against consistency. And modern distributed SQL (Google Spanner, CockroachDB, YugabyteDB) shows CP done well — full ACID transactions across partitions using consensus (Raft/Paxos) and tightly synchronized clocks, paying commit latency for it. ACID vs BASE is a spectrum, not a wall.

Pitfalls

When to use ACID, BASE, or the middle ground

Reach for a single-primary ACID database (PostgreSQL, MySQL/InnoDB, Oracle) when correctness of multi-row invariants is non-negotiable and one machine (plus replicas) can hold your write volume: money movement, inventory decrement, bookings, anything with "must never double-spend / oversell." Signals: you find yourself wanting BEGIN…COMMIT spanning several rows, foreign keys, and uniqueness. Cost: a single write leader is a scaling ceiling and a coordination point; cross-shard transactions are painful.

Prefer a BASE store (Cassandra, DynamoDB, Riak) when write volume or geographic spread exceeds one primary and the domain tolerates brief staleness: activity feeds, telemetry, session/user-profile data, product catalogs, view counters. Signals: partition-friendly access by a single key, append-heavy or independent-per-key writes, must-stay-up-during-a-partition. What you gain: horizontal write scale and availability. What it costs: you own conflict resolution, you lose easy multi-key transactions and ad-hoc joins, and reads can be stale unless you tune R + W > N.

Choose distributed SQL (Spanner, CockroachDB, YugabyteDB) when you want ACID transactions and horizontal scale across regions and can't shard the correctness away. Cost: higher commit latency (cross-region consensus) and operational complexity. Crisp rule: choose single-node ACID when invariants matter and one leader suffices; choose BASE when availability and write scale dominate and staleness is acceptable; choose distributed SQL when you refuse to give up either and will pay latency for it. "SQL = ACID, NoSQL = BASE" is now only a rough heuristic — MongoDB has had multi-document ACID transactions since 4.0, and distributed SQL is ACID at scale.

Takeaways


Re-authored and deepened for this guide. Sources: Mohan et al., "ARIES" (ACM TODS, 1992) for WAL recovery; PostgreSQL documentation on MVCC and transaction isolation; Berenson et al., "A Critique of ANSI SQL Isolation Levels" (SIGMOD 1995) for anomalies and write skew; DeCandia et al., "Dynamo" (SOSP 2007) for BASE/eventual consistency; Gilbert & Lynch's proof of Brewer's CAP conjecture and Daniel Abadi's PACELC; Corbett et al., "Spanner" (OSDI 2012); and Kleppmann, Designing Data-Intensive Applications (chapters 7 and 9).

🤖 Don't fully get this? Learn it with Claude

Stuck on ACID vs BASE Properties in Databases? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **ACID vs BASE Properties in Databases** (System Design) and want to truly understand it. Explain ACID vs BASE Properties in Databases from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **ACID vs BASE Properties in Databases** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **ACID vs BASE Properties in Databases** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **ACID vs BASE Properties in Databases** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes