CAP is the most cited and most misquoted result in distributed systems. The popular version — “pick two of consistency, availability, partition tolerance” — is wrong in a way that matters.
What it actually says
Partitions are not a choice. Networks drop packets, switches fail, cables get cut. If your system spans more than one machine, partitions will happen, and “not tolerating” them means being broken when they do.
So P is a fact, not an option. The theorem is really:
When a partition occurs, you must choose: consistency or availability.
- every reader agrees
- yes
- every request answered
- no
The minority side stops serving rather than risk disagreeing. Nobody ever reads a stale value — and some users get an error. This is what a quorum system does, and what your payments ledger should do.
Why it is narrower than people think
The theorem describes one moment: the partition. Most of the time your network is fine — and CAP says nothing at all about that case.
Which is a problem, because the interesting engineering decisions happen the rest of the time. A system that keeps five replicas in sync on every write is slower than one that does not, partition or no partition.
PACELC fills the gap
Daniel Abadi’s extension states both halves:
If there is a Partition, choose Availability or Consistency. Else, choose Latency or Consistency.
The second clause is the one you live with daily. Strong consistency requires coordination, coordination requires round trips, and round trips are latency. It is not a bug to be optimised away; it is what agreement costs.
| System | Partition | Normally |
|---|---|---|
| DynamoDB (eventual) | PA | EL |
| DynamoDB (strong reads) | PC | EC |
| Cassandra (default) | PA | EL |
| MongoDB | PC | EC |
| PostgreSQL, single primary | PC | EC |
| Spanner | PC | EC |
Consistency is a spectrum, not a switch
CAP’s binary framing hides the useful middle:
- Linearizable — one copy, real-time order. The strongest, and the most expensive.
- Sequential — everyone sees the same order, not necessarily real time.
- Causal — related operations are ordered; unrelated ones may differ. Often the sweet spot, because it is what humans actually notice.
- Read-your-writes — you always see your own changes. Cheap, and it fixes the most common user-visible symptom.
- Eventual — replicas converge, given enough quiet.
Most applications need read-your-writes and causal consistency, and would never notice the absence of linearizability. Reaching for the strongest option because it is easiest to reason about is a real cost.
What to actually do
Identify what genuinely needs strong consistency. Usually money, inventory, and uniqueness constraints — and usually a small fraction of the operations.
Make everything else eventual, and design for it. Show optimistic UI, resolve conflicts explicitly, and use idempotency so retries are safe.
Decide what happens during a partition before it happens. Not “the database will handle it” — what does the user see? An error, a stale value, or a degraded feature? That answer belongs in a design document, because during an incident nobody has time to decide it.