Skip to article
ALGORITHMICSSystem Design
System Design6 min read

CAP and PACELC

The choice you only make during a partition — and the one you make the rest of the time.


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.

The network just split. What do you do?
replica A x = 2
✂ split
replica B unavailable
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.

SystemPartitionNormally
DynamoDB (eventual)PAEL
DynamoDB (strong reads)PCEC
Cassandra (default)PAEL
MongoDBPCEC
PostgreSQL, single primaryPCEC
SpannerPCEC

Consistency is a spectrum, not a switch

CAP’s binary framing hides the useful middle:

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.