CMD Guide
HomeSystem DesignCAP Theorem

Components of CAP Theorem

Consistency, Availability and Partition-tolerance are not three switches you flip on — each is a precise, mechanically testable guarantee about how one node's response relates to operations happening elsewhere, and each is really the top of a spectrum of weaker versions. The introduction settled why a partition forces you to drop C or A; this page dissects the three letters themselves, so you can say exactly what a system is promising, how you would catch it lying, and how strong a version of each you actually need.

Consistency (C): a single-copy illusion, defined as linearizability

The mechanism: a read or write appears to take effect atomically at one instant between the moment you call it and the moment it returns, and those instants respect real time — if operation A finishes before B starts, every replica must order A before B. Equivalently, the whole cluster behaves as if there were exactly one copy of the data. That is linearizability, and it is the C in CAP.

Crucially, C is not binary in practice — it is the strongest rung of a ladder: linearizable > sequential > causal > eventual. Each rung drops a promise. Sequential keeps a single global order but lets it drift from real-time; causal only orders operations that depend on each other; eventual only promises that, if writes stop, replicas converge. CAP-C means the top rung. (And none of this is the C in ACID, which is about transactions preserving declared invariants — an ACID database can still serve stale, non-linearizable reads across replicas.)

Don't confuse linearizability with serializability

The other "strong" guarantee people reach for is serializability, and it is a different axis from CAP-C. Keep them apart:

They are orthogonal — you can have either without the other. PostgreSQL's SERIALIZABLE (serializable snapshot isolation, SSI) is the cleanest witness: every transaction reads from a consistent snapshot taken when it began, so a transaction can commit having read state that predates a write that had already committed in real time — a legal serial order exists, but it does not respect the wall clock. Serializable, not linearizable, and no replica is even involved. (Separately, reads on an async replica are not linearizable for the plainer reason that the replica lags — but don't fuse the two into one example: PostgreSQL refuses SERIALIZABLE on a hot-standby replica outright and raises an error, capping standby queries at REPEATABLE READ.) Conversely a single-object linearizable register (etcd, ZooKeeper) has no multi-object transactions to serialize at all. Combining both — every transaction serial and respecting real-time order — is strict serializability, the guarantee Google Spanner provides (via TrueTime). Interviewers love the follow-up "linearizable vs serializable — can you have one without the other?"; the answer is yes, and strict serializability is their union.

Not serializableSerializable
LinearizableSingle-object linearizable register (etcd, ZooKeeper) — no multi-object txnsStrict serializability — Spanner
Not linearizableEventual-consistency store (Cassandra/Dynamo default)Postgres SERIALIZABLE (SSI reads from a possibly-stale snapshot)
diagram
diagram

A traced example: judging a real operation history

Linearizability is checked, not asserted. You take the log of overlapping operations on a register x (initial value 0) and ask: does there exist one point-in-time for each operation, inside its own call–return window, that makes all reads correct? Two histories, same three clients:

OpReal-time windowReturns
A: write x := 1t0 → t5ack
B: read xt2 → t30
C: read xt6 → t71

Verdict: linearizable. Place the write's effect at t≈4. B (t2–t3) is entirely before that point, so reading 0 is legal; C (t6–t7) is entirely after, so it must — and does — read 1. One consistent story exists.

Now change only C's return value in a history where B reads after the write completes:

OpReal-time windowReturns
A: write x := 1t0 → t5ack
B: read xt6 → t71
C: read xt8 → t90

Verdict: NOT linearizable. Once B observed 1 (and the write had already completed), value 0 is gone forever; a later read returning 0 means the register went backwards in time. No single instant explains it. This is the exact failure a strongly-consistent store must prevent — and the reason it may have to block or error under a partition.

Availability (A): every live node answers, in bounded time

The mechanism: every request sent to a non-crashed node returns a non-error response within a bounded time — it may be stale, but the node never hangs and never says "try again later." That is a stricter, more theoretical bar than the operational "availability" on a status page.

The trap is conflating CAP-A with an SLA of nines. They are different axes. A CP store like etcd can post 99.99% annual uptime and still have zero CAP-availability the moment a partition isolates it, because by design the minority side returns errors. Conversely, the "bounded time" clause means a node that takes 30 seconds to answer is, for practical purposes, unavailable even though it never errored. High uptime does not imply CAP-A, and CAP-A does not require perfect uptime — it requires never withholding an answer from a working node.

Partition tolerance (P): surviving lost messages between live nodes

The mechanism: the system keeps operating when messages between nodes are dropped or arbitrarily delayed, splitting the cluster into groups that cannot communicate. Note what a partition is not: it is not a node crashing (that is just reduced capacity) — it is two live nodes that can no longer hear each other. That definition is broader than most engineers assume: a one-way (asymmetric) link where N1 hears N2 but not vice-versa is a partition; a GC pause or a saturated NIC that stalls heartbeats past their timeout is, to the rest of the cluster, indistinguishable from a cut cable.

This is why P is not a choice. Take nodes in New York and London: no vendor sells a transatlantic link that never drops a packet, and even a single missed heartbeat window is a partition. You cannot design partitions away; you can only decide what each side does during one. So on any real multi-node network P is mandatory, and the genuine dial is how strong a C you can afford to keep while still tolerating it.

Pitfalls

When to use it / how strong a consistency do you need

Because P is forced and A is often non-negotiable for user-facing systems, the component you most actively tune is the strength of C. Pick the weakest rung that still makes your invariant safe — stronger costs coordination, latency, and availability under partition.

Crisp rule: use linearizable only for the handful of operations where a wrong-order read corrupts state; drop to causal when you just need effects to follow their causes while staying available; and use eventual for the majority of reads where a few seconds of staleness is invisible to the user.

Takeaways


Re-authored and deepened for this guide. Sources: M. Herlihy & J. Wing, "Linearizability: A Correctness Condition for Concurrent Objects" (ACM TOPLAS, 1990); S. Gilbert & N. Lynch, "Brewer's Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services" (2002); E. Brewer, "CAP Twelve Years Later" (IEEE Computer, 2012); L. Lamport on sequential consistency (1979); Ahamad et al., "Causal Memory" (1995); Lloyd et al., "Don't Settle for Eventual" (COPS, SOSP 2011); P. Viotti & M. Vukolić, "Consistency in Non-Transactional Distributed Storage Systems" (ACM Computing Surveys, 2016).

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

Stuck on Components of CAP Theorem? 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 **Components of CAP Theorem** (System Design) and want to truly understand it. Explain Components of CAP Theorem 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 **Components of CAP Theorem** 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 **Components of CAP Theorem** 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 **Components of CAP Theorem** 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