Fundamentals

Consistency and CAP

What the CAP theorem actually forces you to give up, and when to choose strong vs. eventual consistency.

11 minMediumconsistencydistributed-systemsfundamentals

The CAP theorem gets cited constantly and applied badly. Candidates who say "CAP theorem" without being able to say what it actually forces them to give up tend to lose points rather than gain them.

What CAP actually says

When a network partition happens — and in a distributed system, eventually one will — you have to choose between:

  • Consistency: every read sees the most recent write, or an error.
  • Availability: every request gets a response, even if it might be stale.

You don't get to choose both during the partition. Outside of a partition, most systems are both consistent and available; CAP only bites when the network actually splits.

PACELC: what CAP leaves out

CAP only describes behavior during a partition — but even when the network is healthy, a system with replicas still has to choose between latency and consistency on every single request. PACELC names this explicitly: if Partitioned, choose Availability or Consistency; Else (normal operation), choose Latency or Consistency. A system that requires every write to reach a quorum of replicas before acknowledging — strong consistency, in the table below — pays that round-trip latency on every write, partition or not; that's the "else" half of PACELC, and it's a real, everyday cost, not just a failure-mode cost. DynamoDB and Cassandra being tunable per-request isn't only about surviving partitions — it's letting the caller make this latency/consistency trade on every single call.

Strong vs. eventual consistency, concretely

Strong consistencyEventual consistency
A read right after a writeAlways sees the new valueMay see the old value briefly
Typical costHigher write latency, coordination overheadLower latency, simpler scaling
Good fitAccount balances, inventory countsView counts, "last seen online", feeds

A concrete example worth having ready

A checkout flow that decrements inventory needs strong consistency on the inventory count — two customers cannot both successfully buy the last item. The same checkout flow's "12 people are viewing this item" counter can be eventually consistent; being off by a few for a couple of seconds costs nothing.

Naming which parts of your design need which guarantee — rather than picking one consistency model for the whole system — is usually the signal an interviewer is listening for at this point in the conversation.

Quorum reads and writes, briefly

A common middle ground: require a write to succeed on W out of N replicas, and a read to check R out of N. When W + R > N, every read is guaranteed to overlap with the most recent write, giving you strong consistency without requiring all N replicas to be reachable. With N = 3, W = 2, R = 2 — a common default — W + R = 4 > 3, so any read and any write are guaranteed to share at least one replica, while the system still tolerates one replica being down.

This isn't hypothetical: DynamoDB lets a caller choose per-request between an eventually consistent read (cheaper, may lag replication by a few milliseconds) and a strongly consistent read (more expensive, guaranteed latest) — a production example of leaving this exact choice to the caller instead of baking one model into the whole system. Cassandra exposes the same idea more directly, with a tunable consistency level (ONE, QUORUM, ALL) set per query.

Before a partition

Client

Replica A

Replica B

Replica C

all three in sync

During a partition — A is cut off from B and C — the two choices diverge:

CP choice

Client

Replica A

refuses — can't confirm quorum

AP choice

Client

Replica A

serves local state, may diverge

It's worth being able to draw this trade-off even if you don't reach for quorum systems by name.