A distributed data store can only fully guarantee two of consistency, availability, and partition tolerance. In any real network, partitions WILL happen — so you're effectively choosing between CP (refuse stale reads when partitioned) and AP (keep serving but accept stale data). The "CA" corner is a single-machine system. The pick is per-system, sometimes per-API.
Every time you design a distributed data store, you implicitly pick a CAP corner. Knowing which one tells you immediately how the system behaves under failure — whether reads return stale data, whether writes are accepted, whether the service stays up. Modern systems (Cassandra, DynamoDB, MongoDB) have tunable consistency knobs that let different operations pick different corners.
Pick a corner
The theorem in one sentence
Eric Brewer’s 2000 conjecture (proven 2002 by Gilbert & Lynch):
Twenty-five years later, this is the most-cited and most-misunderstood result in distributed systems.
Why “pick two” is misleading
The problem with “pick two” is that partition tolerance isn’t really optional in any real network. Packets drop, switches die, fiber gets cut. If your system runs across more than one machine, you must handle partitions — there’s no “we’ll just not have any.”
The CP vs AP fork, visualised
flowchart TD
P[Network partition occurs<br/><i>switch dies, link drops, region goes dark</i>]
P --> Q{System detects<br/>partition}
Q -->|CP choice| CP[CP — Consistency wins]
Q -->|AP choice| AP[AP — Availability wins]
CP --> CP1[Minority side stops<br/>accepting writes<br/><i>no quorum</i>]
CP --> CP2[Some reads return errors<br/>instead of stale data]
CP --> CP3[Majority side continues<br/>at reduced capacity]
CP --> CPex[Etcd · Zookeeper · Spanner ·<br/>MongoDB default · HBase]
AP --> AP1[Both sides accept writes]
AP --> AP2[Reads return whatever<br/>local replica has]
AP --> AP3[Conflicts reconciled later<br/><i>LWW · vector clocks · CRDTs</i>]
AP --> APex[Cassandra · DynamoDB ·<br/>Riak · CouchDB]
style P fill:#7e1d1d,stroke:#ef4444,color:#fff
style Q fill:#9a3412,stroke:#f97316,color:#fff
style CP fill:#1e3a8a,stroke:#3b82f6,color:#fff
style AP fill:#0e7490,stroke:#06b6d4,color:#fff
style CP1 fill:#0f1320,stroke:#475569,color:#cdd3df
style CP2 fill:#0f1320,stroke:#475569,color:#cdd3df
style CP3 fill:#0f1320,stroke:#475569,color:#cdd3df
style AP1 fill:#0f1320,stroke:#475569,color:#cdd3df
style AP2 fill:#0f1320,stroke:#475569,color:#cdd3df
style AP3 fill:#0f1320,stroke:#475569,color:#cdd3df
style CPex fill:#581c87,stroke:#a855f7,color:#fff
style APex fill:#365314,stroke:#84cc16,color:#fff
What CP looks like in practice
A CP system, on detecting a partition, refuses to serve some clients to preserve consistency:
- The minority side of the partition stops accepting writes (it can’t reach quorum)
- Some reads return errors instead of stale data
- The majority side continues, but with reduced capacity
You see this with Etcd, Zookeeper, MongoDB (default), HBase. They use Raft, ZAB, or Paxos to ensure linearizable reads and writes.
What AP looks like in practice
An AP system, on partition, keeps every replica answering — accepting that they may temporarily disagree:
- Both sides of the partition accept writes
- Reads return whatever the local replica has
- Conflicts are reconciled later (last-write-wins, vector clocks, CRDTs)
You see this with Cassandra, DynamoDB, Riak, CouchDB. They optimize for “always responsive” and provide tunable consistency — you can ask for stronger guarantees per-operation if you need them.
The right choice depends on what’s worse
For many domains, brief inconsistency is fine but downtime isn’t:
- Social feeds (eventually consistent likes/comments)
- Shopping carts (always accept items, reconcile at checkout)
- Sensor data (last value wins is fine)
For other domains, stale data is dangerous:
- Bank transfers (don’t show the balance before the deposit settled)
- Inventory (don’t sell the same item twice)
- Locks and leases (only one holder at a time)
Comments 0
Discuss this page. Markdown supported. Be kind.