CAP & PACELC
Almost everyone has heard “CAP theorem: pick two of three.” Almost everyone has it slightly wrong. CAP is not a buffet where you calmly choose two of Consistency, Availability, and Partition tolerance. It is a statement about a single, specific, unavoidable moment: when the network partitions, you must sacrifice either consistency or availability — there is no third option. This page states CAP precisely, then upgrades it to PACELC, which exposes the trade-off you pay the other 99% of the time, when nothing is broken at all.
If you want the gentle on-ramp first, read CAP intuition; this page is the rigorous version.
CAP, stated precisely
Section titled “CAP, stated precisely”Define the three terms the way the theorem actually means them:
- Consistency (C) — here, linearizability. Every read sees the most recent write; the system behaves as if there were one copy of the data. (This is a strong, specific definition — see Consistency Models.)
- Availability (A) — every request to a non-failing node returns a non-error response, eventually.
- Partition tolerance (P) — the system keeps operating despite the network dropping or delaying arbitrary messages between nodes.
The real theorem is sharper than “pick two”:
In the presence of a network partition, a distributed system cannot be both consistent (linearizable) and available. It must choose.
P is not really optional. Networks will partition — cables get cut, switches reboot, a data center loses a link. You don’t get to “choose not to tolerate partitions”; you only choose how you behave when one arrives. So CAP is honestly a binary: during a partition, are you CP or AP?
Partition happens. A client writes to one side, reads from the other.
CP choice (Consistency): AP choice (Availability): ────────────────────── ───────────────────────── Refuse to serve on the side that Serve on both sides. Both stay up. can't confirm it has the latest But the two sides may now return data. Some requests ERROR or hang. DIFFERENT (stale) answers.
You kept correctness, You kept uptime, you lost availability. you lost consistency.Why the choice is forced (the one-line proof)
Section titled “Why the choice is forced (the one-line proof)”Imagine two nodes, N1 and N2, holding a replica of value x, and the link between them dies. A
client writes x = 2 to N1. Another client reads x from N2. N2 has not heard about the write —
the link is down. N2 now has exactly two options: return the old value (x = 1, breaking
consistency) or refuse to answer until it can sync (breaking availability). There is no third
move. That’s the whole proof. Everything else is engineering around this corner.
PACELC: the trade-off CAP forgets
Section titled “PACELC: the trade-off CAP forgets”CAP only speaks about the partition case, which is rare. Daniel Abadi’s PACELC completes the picture by naming the trade-off that applies all the rest of the time:
IF (P)artition: choose (A)vailability or (C)onsistency ELSE (E): choose (L)atency or (C)onsistency
P → A | C E → L | CRead it as a sentence: “If there’s a Partition, choose Availability or Consistency; Else, choose Latency or Consistency.” The “else” branch is the insight. Even with a perfectly healthy network, keeping replicas linearizable means a write must reach a quorum of nodes — possibly across regions — before it’s acknowledged. That coordination costs latency. If you’d rather answer fast, you must accept replicas that are momentarily out of sync. So the consistency-versus-something tension never goes away; a partition just changes what “something” is (availability) from what it usually is (latency).
This is why PACELC is the more useful lens for real design: you will spend far more time in E than in P, and the latency-vs-consistency choice quietly shapes every user-facing read.
Mapping real databases to the choice
Section titled “Mapping real databases to the choice”These are defaults — most systems offer knobs (tunable consistency, sync vs async replication) that move them around. Treat the table as “where it sits out of the box.”
| System | Partition (P) | Normal (E) | PACELC class |
|---|---|---|---|
| Classic single-leader SQL (Postgres, sync replica) | CP | EC | PC/EC |
| Spanner / etcd / ZooKeeper | CP | EC | PC/EC |
| DynamoDB / Cassandra (default) | AP | EL | PA/EL |
| MongoDB (default, majority writes) | CP | EC | PC/EC |
Cassandra tuned to QUORUM reads+writes | CP-ish | EC | PC/EC |
Two readings worth internalizing. First, the “Dynamo lineage” (Dynamo, Cassandra, Riak) chose PA/EL on purpose: stay up under partition, stay fast normally, and let applications repair conflicting versions later — built for shopping carts and timelines where a stale read is survivable. Second, coordination systems (etcd, ZooKeeper, Spanner) chose PC/EC on purpose: they hold the truth that everything else depends on — leader identity, locks, config — where a wrong answer is far worse than a slow or absent one. The choice tracks the cost of being wrong.
So: what does it buy us, and what does it cost?
Section titled “So: what does it buy us, and what does it cost?”Choosing AP/EL buys you a system that never tells a user “sorry, try later” and answers fast — at the cost of occasionally serving stale or conflicting data your application must reconcile. Choosing CP/EC buys you a single, trustworthy version of reality everyone can build on — at the cost of refusing service during partitions and adding coordination latency the rest of the time. CAP and PACELC don’t tell you which to pick. They tell you the bill always comes due, and they make sure you sign for it knowingly instead of discovering the charge in production.
Check your understanding
Section titled “Check your understanding”- Why is “pick two of three” a misleading summary of CAP? State what the theorem actually constrains.
- Walk through the two-node proof: when the link between N1 and N2 dies and a read arrives at the stale node, what are its only two options, and which CAP property does each sacrifice?
- What does the “ELC” half of PACELC add that CAP omits, and why does it matter more often in practice?
- Why did the Dynamo lineage choose PA/EL while etcd and ZooKeeper chose PC/EC? Tie it to the cost of returning a wrong answer.
- In what sense is a single-node database “CA,” and why does that make CA an unhelpful label for distributed systems?