Three promises
Eric Brewer proposed the idea in a talk in 2000. Seth Gilbert and Nancy Lynch proved it in 2002. It talks about three promises a system with copies on several servers might make.- Consistency (C). Every read sees the latest write, no matter which server answers. If Hanoi accepted the $50, Lisbon must not say $100. Formally this is called linearizability. It is not the “C” in ACID, which is about following database rules like foreign keys.
- Availability (A). Every request to a working server gets a real answer, not an error, even if other servers are cut off.
- Partition tolerance (P). The system keeps running when messages between servers are lost or delayed. A partition is that break: two groups of servers that cannot reach each other.
Why “pick two of three” misleads
CAP is often drawn as a triangle with the advice “pick any two”. That makes three options look equal: CP, AP and CA. They are not. A system with copies on two machines cannot promise that the cable never breaks. Cables get cut, switches reboot, and cloud regions lose contact. So “giving up P” is not a real choice. A database that claims to be CA either runs on one machine or quietly picks C or A when a partition finally comes. Two more details matter:- The choice only applies during a partition. When the network is healthy, a system can be both consistent and available. Brewer made this point himself in 2012: the “2 of 3” framing was always misleading.
- The choice is not all-or-nothing. One system can refuse some requests and answer others. It can also pick differently for different data.
CP and AP in real databases
Two popular databases make opposite default choices. MongoDB leans CP. Cassandra leans AP. Figure 3 hits both with the same network split. MongoDB stores data in a replica set: one primary that takes all writes, plus copies called secondaries. If the primary cannot reach most of the set, it steps down. The servers on the bigger side elect a new primary. MongoDB’s docs say this usually takes no more than about 12 seconds with default settings. During that time writes cannot be accepted. Reads can still be served from secondaries if the app allows it, but they may be stale. Cassandra has no primary. Any copy can accept a write. During a split, both sides keep working, and their copies drift apart. When the network heals, Cassandra fixes the gaps: a node replays writes it held for the missing node (hinted handoff), reads compare copies and fix them (read repair), and an operator can run a fullnodetool repair.
These are defaults, not fixed labels. Both systems let each request choose:
- Cassandra’s
QUORUMlevel requires a majority of copies to answer. Use it for both reads and writes, and every read sees the latest write. The price: the minority side of a split now returns errors, just like a CP system. - MongoDB’s write concern and read preference settings go the other way. You can wait for fewer copies to confirm a write, or read from secondaries that may lag. That trades some consistency for speed and availability.
Choosing per service
In a microservice design, each service usually owns its own database. That means CAP is not one decision for the whole company. Each service asks its own question: during a split, is a wrong answer or no answer worse? Relational databases like PostgreSQL do not escape this. Once you copy a PostgreSQL database to another server, the same question applies. With synchronous replication, a write waits until the copy confirms it, so a split blocks writes. That behaves like CP. With asynchronous replication, writes do not wait, so a failover can serve old data or lose recent writes.When the network is fine: PACELC
CAP only covers the moments when the network is split. Those are rare. The rest of the time, every write still forces a choice when it reaches Hanoi:- Answer now and copy to Lisbon in the background. The app hears OK fast, but for a moment Lisbon is behind and can give a stale answer.
- Wait for the copy. Hanoi says OK only after Lisbon confirms. Every read is correct, but each write pays a round trip between the two cities.
- If there is a Partition (P): choose Availability (A) or Consistency (C). This is CAP.
- Else, when the network is fine (E): choose Latency (L) or Consistency (C). This is Figure 5.
As with CAP, these labels describe defaults. Tunable settings move most databases between classes.
Check yourself
Glossary
For AI agents
Adapted from IBM, “What is the CAP theorem?”, with corrections: CAP is a choice made during partitions rather than “any two of three”; CAP consistency is not ACID consistency; replicated PostgreSQL is not CA; and MongoDB and Cassandra are CP and AP only by default. Further reading: Eric Brewer, “CAP Twelve Years Later”; MongoDB, “Replica Set Elections”. Figures are simplified teaching models; timings in Figure 3 are illustrative.