6 min read

Q39 — What is the CAP theorem — and why is it almost always misunderstood?


What does CAP actually say?

The CAP theorem, proven by Eric Brewer and formally demonstrated by Gilbert and Lynch in 2002, states:

In the presence of a network partition, a distributed system can guarantee either Consistency or Availability — but not both simultaneously.

Three properties:

Consistency (C): Every read returns the most recent write (or an error). This is linearizability — the same strong consistency defined in Q38.

Availability (A): Every request to a non-failing node receives a response (not an error). The system doesn't hang, doesn't reject, doesn't say "I don't know." It answers.

Partition tolerance (P): The system continues operating even when some messages between nodes are lost or delayed. The network can be partitioned — split into two groups that can't communicate — and the system keeps running.

The theorem says: when a partition occurs, you must choose between C and A.


Why is CAP almost always misunderstood?

The most common misunderstanding: treating CAP as a spectrum where you choose a design point between the three properties as engineering trade-offs, as if you can dial up more consistency while dialing down availability at any time, independently of network conditions.

Misunderstanding 1: P is optional. Some engineers read "CA systems" (no partition tolerance) as a valid architectural choice. This is wrong for any real distributed system. Networks partition. Machines lose connectivity. Power cables are cut. If you have more than one machine communicating over a network, you will eventually experience a partition. "CA without P" means: a system that works fine when the network is perfect, and fails completely when it isn't. That's just a bad system, not a CAP trade-off. Partition tolerance is not optional. CAP is really CP vs AP.

Misunderstanding 2: The choice is permanent. Engineers say "we're a CP system" or "we're an AP system" as if the system has a fixed character. In reality, the choice applies only during a partition. When the network is healthy, a well-designed system provides both consistency and availability. The choice is between C and A only when you're forced to make it — during a partition.

Misunderstanding 3: C and A are binary. CAP's C is specifically linearizability. CAP's A is specifically "every request gets a response." Both are all-or-nothing in the theorem's proof. In practice, consistency is a spectrum (Q37) and availability is a spectrum (some requests might time out). The theorem's binary definitions don't cleanly map to real systems.

Misunderstanding 4: CAP covers everything important. CAP says nothing about latency. A CP system that's linearizable is still correct if it takes 5 seconds to respond during normal operation. CAP says nothing about partition duration. A system that blocks for 30 minutes during a partition before resuming is CAP-consistent (it chose C over A) but practically useless.


What actually happens during a partition?

Imagine a database with two nodes — Primary in Region A, Replica in Region B — connected by a network link. The network link fails (a partition).

Now Primary has some writes it hasn't sent to Replica yet. New write requests keep arriving at Primary.

If the system chooses Consistency (CP): The Primary must stop accepting writes (or reads that might return stale data) because it can't guarantee the Replica won't serve inconsistent reads during the partition. It returns errors: "service unavailable." Users can't complete transactions. The system is consistent (no stale reads served) but unavailable.

When the partition heals, the system syncs and resumes serving. No inconsistency was introduced.

If the system chooses Availability (AP): Both nodes keep accepting reads and writes independently. The Primary accepts new writes. The Replica serves reads from its pre-partition state. Users in Region A see current data. Users in Region B see stale data (or potentially their own diverging writes). The system is available (everyone gets responses) but inconsistent (different nodes serve different values).

When the partition heals, the system must reconcile diverged state — conflict resolution, last-write-wins, or application-level merge.


What do real systems actually choose?

CP systems: ZooKeeper, etcd, Consul, HBase. When a partition means a quorum cannot be reached, they stop accepting writes. They return errors rather than serve potentially inconsistent data. This makes them appropriate for coordination, distributed locking, and configuration storage — where serving stale data would be worse than refusing to serve.

AP systems: Cassandra, DynamoDB (by default), CouchDB, Riak. During a partition, all nodes keep accepting reads and writes. Data diverges. When the partition heals, conflict resolution runs. This makes them appropriate for high-availability data where stale reads are tolerable — shopping carts, social feeds, product catalogs.

Nuance: Cassandra is AP by default, but with quorum reads/writes (W + R > N) it behaves as CP. DynamoDB offers strongly consistent reads as an option. Many "AP" systems let you dial toward CP for specific operations. The CAP choice is not always all-or-nothing at the system level.


What is PACELC — the more practical model?

CAP only talks about behavior during partitions. But partitions are rare. Engineers make decisions about their system's behavior during normal operation too — and the CAP theorem has nothing to say about that.

The PACELC model extends CAP: during a Partition (P), choose between Availability (A) and Consistency (C). Else (E) — when there's no partition — choose between Latency (L) and Consistency (C).

The second trade-off is constant, not just during failures. Even without a partition, a strongly consistent write is slower than an eventually consistent write — it must coordinate with replicas before acknowledging. This latency-consistency trade-off is present on every single write, not just during network partitions.

PACELC makes explicit what CAP obscures: the everyday performance cost of consistency, not just the failure-mode cost. Real engineering decisions are mostly about PACELC's ELC component — whether normal-operation latency is worth the consistency guarantee — not about the rare partition scenario.

Systems classified under PACELC:

  • DynamoDB: PA/EL — AP during partition, favors low latency over consistency during normal operation
  • Cassandra: PA/EL — same
  • CockroachDB: PC/EC — CP during partition, favors consistency (and accepts higher latency) during normal operation
  • Spanner: PC/EC — strongly consistent always, using GPS/atomic clocks to minimize the latency penalty

The mental model

code
CAP theorem (the precise statement):
  During a network partition, you cannot have both:
    C: every read returns the most recent write (linearizability)
    A: every request to a non-failing node gets a response

  P (partition tolerance) is not optional — networks always partition eventually
  → CAP is really: during a partition, choose CP or AP

CP: reject reads/writes if quorum unreachable → consistent, unavailable during partition
    ZooKeeper, etcd, HBase
    Use for: coordination, locks, config (stale data = wrong decision)

AP: serve reads/writes on all reachable nodes → available, inconsistent during partition
    Cassandra, DynamoDB, CouchDB
    Use for: high-availability data where staleness is tolerable

Common misunderstandings:
  "CA is a choice" → wrong, P is mandatory for any real distributed system
  "The choice is fixed" → wrong, applies only during partition; both C and A during normal ops
  "C and A are binary" → wrong in practice; both are spectrums

PACELC (more useful model):
  During Partition → A vs C (same as CAP)
  Else (normal operation) → Latency vs Consistency
  The everyday trade-off: low latency eventual writes vs higher latency linearizable writes
  This is present on every write, not just during failures

CAP is a theorem, not a design tool. Its value is understanding why you can't have everything during a network failure. PACELC is the design tool — it captures the constant, everyday trade-off between latency and consistency that actually drives system design decisions. Knowing CAP impresses interviewers; understanding PACELC shapes better systems.