CAP theorem simulator
The CAP theorem says that when the network between the parts of a distributed database fails, the database has to choose: refuse some requests to stay consistent, or keep answering and risk giving out-of-date answers. Cut the network below and try both. Further down are a worked example, CP and AP databases compared, and how the theorem comes up in system design interviews.
The network is working, so every write reaches all three replicas.
How to use the simulator
The simulator keeps three copies, or replicas, of a single value called x. Client 1 talks to replica R1 and client 2 talks to replica R3. While the network is working, every write is copied to all three replicas, so both clients always read the same value.
Press Cut the network to separate R3 from R1 and R2, then write and read from both clients:
- With Prefer consistency (CP), a replica answers only if it can reach a majority of the replicas, which here means two of the three. R1 and R2 can, so client 1 keeps working. R3 cannot, so client 2's requests are refused.
- With Prefer availability (AP), every replica answers. Client 2 can keep writing to R3, but its reads may return an old value, and the two sides drift apart.
Press Repair the network to see how the replicas catch up. In AP mode, if both sides accepted writes, the simulator keeps the most recent one, a rule called "last writer wins", and the writes from the other side are lost even though they were acknowledged. The counters at the top count what happened.
The model is deliberately small. Real systems add leaders, timeouts, retries and more replicas, and many use smarter ways of merging conflicting writes than "last writer wins". They still face the same choice whenever replicas cannot reach each other.
What is the CAP theorem?
The CAP theorem says that a distributed data store cannot guarantee all three of the following properties at the same time:
- Consistency: every read returns the most recent write, or an error;
- Availability: every request to a working node gets a response;
- Partition tolerance: the system keeps working even when the network loses messages between nodes.
Network failures cannot be ruled out in a system that runs on more than one machine, so the theorem is usually read like this: when the network splits, a system has to choose between consistency and availability. It can refuse some requests so that it never gives an out-of-date or conflicting answer, or it can answer every request and accept that some answers may be out of date.
The idea was put forward by Eric Brewer in 2000 and proved by Seth Gilbert and Nancy Lynch in 2002. It is also known as Brewer's theorem.
The three properties
Gilbert and Lynch's proof uses precise definitions, and these differ from the everyday meaning of the words.
Consistency
Consistency in CAP means linearizability. The system behaves as if there were a single copy of the data, and each operation takes effect at one instant between the moment it starts and the moment it finishes. Once a write has completed, every later read, from any client and any node, returns that value or a newer one.
Availability
Availability means that every request received by a node that has not failed eventually gets a response that is not an error. This is a strict requirement. A system that answers only from the side of a partition that holds a majority of the nodes is not available in this sense, even if most clients never notice the difference.
Partition tolerance
Partition tolerance means the system keeps working even if the network loses any number of messages between nodes. A partition is a period in which some nodes cannot communicate with others, for example because a switch fails, a firewall rule is wrong or the link between two data centres is cut. The nodes themselves are still running.
Why all three are impossible
The argument needs only two replicas. Suppose replicas G1 and G2 cannot communicate. A client writes a new value to G1. To be available, G1 must accept the write and reply. Another client then reads from G2. To be available, G2 must also reply, but it has had no way of learning about the write, so it returns the old value, and consistency is broken.
No algorithm can avoid this, because G2 cannot tell this situation apart from one in which no write happened at all. That is the core of Gilbert and Lynch's proof. In practice, each side of a partition has two options:
- refuse requests until it can be sure it has the latest data, which gives up availability (a CP choice); or
- keep answering, and reconcile the differences once the network recovers, which gives up consistency (an AP choice).
CAP theorem example
Here is one sequence of steps run through the simulator above twice, once in each mode. Client 1 writes before the network is cut, so all three replicas hold x = a1. The network is then cut, leaving R1 and R2 on one side and R3 on the other. Both clients write, then both read, then the network is repaired.
| Step | Prefer consistency (CP) | Prefer availability (AP) |
|---|---|---|
| Client 1 writes a2 through R1 | Accepted: R1 and R2 are a majority | Accepted by R1 and R2 |
| Client 2 writes b1 through R3 | Refused: R3 is alone | Accepted by R3 |
| Client 1 reads from R1 | a2, up to date | a2, stale: b1 is newer |
| Client 2 reads from R3 | Refused | b1 |
| Network repaired | R3 copies a2; nothing lost | Last writer wins: all keep b1, and a2 is lost |
| Counters at the end | 2 accepted, 2 refused, 0 stale, 0 lost | 3 accepted, 0 refused, 1 stale, 1 lost |
Neither column is free of cost. The CP system turned away every request from client 2 for as long as the partition lasted. The AP system answered everything, but one read was out of date and one write that had been acknowledged to client 1 disappeared when the two sides were merged. Which cost is acceptable depends on what the data is.
Common misunderstandings
"Pick any two of three"
The popular summary is misleading. Partition tolerance is not optional for a system that runs on more than one machine, because networks do fail. The choice applies only while a partition lasts, and only between consistency and availability. When the network is working, a system can be both consistent and available. Brewer made this point himself in 2012.
"CA" systems
A database on a single server is sometimes called CA. It has no network between replicas that could split, so the question does not arise. But if that server, or its own network connection, fails, the database is simply unavailable. The label is only meaningful for systems that do not replicate across a network.
Every system is either CP or AP
Many real systems are neither in the strict sense of the theorem. A database with one leader and asynchronously updated followers can lose acknowledged writes when the leader fails, so it is not consistent; and clients that cannot reach the leader cannot write, so it is not available either. In 2015 Martin Kleppmann argued that it is more useful to describe the guarantees a system offers than to label it CP or AP. Many databases also let each request choose its own trade-off.
Consistency means the same as in ACID
The C in ACID means that a transaction leaves the database in a valid state that satisfies its rules and constraints. The C in CAP means linearizability. They are unrelated properties that happen to share a word.
CAP describes performance
The theorem says nothing about how fast a system is when the network is healthy. That trade-off is the subject of PACELC, described below.
History
Eric Brewer, a professor at the University of California, Berkeley and a co-founder of the search company Inktomi, presented the idea as a conjecture in his keynote at the ACM Symposium on Principles of Distributed Computing (PODC) in July 2000. In 2002 Seth Gilbert and Nancy Lynch of MIT published a formal proof in SIGACT News, in a paper titled Brewer's Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services.
In 2012 Brewer published CAP Twelve Years Later: How the "Rules" Have Changed in IEEE Computer. He argued that the "two of three" formulation is misleading and that designers should think instead about how a system behaves during a partition and how it recovers afterwards. In 2017 he described Google's Spanner database as technically CP but "effectively CA": Google's private network makes partitions rare enough that Spanner is almost always available in practice.
A related but different result is the FLP impossibility proof of 1985 by Fischer, Lynch and Paterson, which shows that agreement between processes cannot be guaranteed in a fully asynchronous network if even one process may crash.
PACELC
The CAP theorem only describes what happens during a partition. Daniel Abadi pointed out that replicated systems face a second trade-off all the time: even when the network is working, keeping replicas consistent means waiting for messages between them, and that adds latency. He described the idea in a blog post in 2010 and in an article in IEEE Computer in 2012, using the name PACELC:
If there is a partition, the system trades availability against consistency; else, when the system is running normally, it trades latency against consistency.
In Abadi's article, Dynamo, Cassandra and Riak are PA/EL: they favour availability during a partition and low latency otherwise. VoltDB/H-Store and Megastore are PC/EC. MongoDB was classed as PA/EC and Yahoo's PNUTS as PC/EL. Many of these systems can now be configured to behave differently, so the labels describe default designs, not fixed rules.
How real databases behave
Most production systems do not fit neatly into one category, and many can be configured per request. These are their usual behaviours during a partition. Check each system's documentation for the version and settings you use.
| System | During a partition | Notes |
|---|---|---|
| etcd, ZooKeeper, Consul | Only the side with a majority of members accepts writes. | Built on consensus protocols (Raft or Zab). etcd serves linearizable reads by default. |
| Spanner, CockroachDB | Data whose replicas lose their majority becomes unavailable. | Consensus (Paxos or Raft) for each range of data. |
| Cassandra | Depends on the consistency level of each request. ONE keeps answering; QUORUM needs a majority of the replicas for that row. | Conflicting writes are resolved by timestamp (last write wins). |
| DynamoDB | Reads are eventually consistent by default; strongly consistent reads can be requested for each read. | Global tables replicate between Regions asynchronously by default; a multi-Region strong consistency mode is also available. |
| MongoDB | Only the side with a majority can elect a primary and accept writes. | With write concern w: 1, acknowledged writes can be rolled back after a failover; w: "majority" avoids this. |
| PostgreSQL or MySQL with asynchronous replicas | Clients that cannot reach the primary cannot write; replicas can serve stale reads. | Promoting a replica after a failure can lose the most recent writes. |
CP vs AP: how to choose
The question to ask is what is worse for this piece of data: a request that fails, or an answer that is wrong or later undone. The same application often answers it differently for different data.
| Data | Usual choice | Why |
|---|---|---|
| Locks, leader election, cluster configuration | CP | Two nodes that both think they hold a lock, or both think they lead, can corrupt data. etcd and ZooKeeper refuse instead. |
| Account balances, payments, the last seat or item in stock | CP | Selling the same seat twice or spending the same money twice has to be undone by hand. |
| Shopping carts | AP | Amazon’s Dynamo paper describes keeping carts writable during failures and merging the copies afterwards. A deleted item can reappear, which costs less than a lost sale. |
| DNS records, CDN caches | AP | Serving a record or file that is a few minutes old is better than serving nothing; each answer carries a time to live. |
| Likes, view counts, social feeds | AP | A count that is briefly off is invisible to users; an error page is not. |
Many designs mix the two. In CAP Twelve Years Later, Brewer uses a cash machine as the example: when it cannot reach the bank, it can keep working in a limited mode, letting customers withdraw up to a fixed amount and settling the account once the connection is back. The system stays available, and the business caps how much an inconsistency can cost.
Consistency models
The consistency in CAP is linearizability, defined by Maurice Herlihy and Jeannette Wing in 1990. It is about individual operations on individual objects, and it respects real time: once a write has completed, every later read sees it.
Serializability, which comes from database transaction theory in the 1970s, is a different guarantee. It says that concurrent transactions produce the same result as if they had run one at a time in some order, but that order does not have to match real time. Strict serializability combines the two; Spanner and FoundationDB are examples of databases that offer it.
Many systems offer weaker models, such as causal consistency, read-your-writes or eventual consistency, which allow more availability or lower latency. The Jepsen project's consistency-models page shows how these models relate to each other.
Detecting a partition
A node cannot see a partition directly. It only notices that messages from another node have stopped arriving, and that could also mean the other node has crashed or is just slow, for example during a long garbage-collection pause. Systems therefore rely on heartbeats and timeouts.
Choosing the timeout is a trade-off. A short timeout causes unnecessary failovers when a node is merely slow; a long one leaves the system waiting for a node that has died. etcd's defaults, for example, are a 100 ms heartbeat interval and a 1,000 ms election timeout. Cassandra and Akka use the φ accrual failure detector (Hayashibara and others, 2004), which reports a level of suspicion that grows the longer a heartbeat is overdue, instead of a simple yes or no.
Split brain and fencing
Split brain happens when both sides of a partition believe they are in charge and accept writes independently, so the data diverges. Consensus protocols such as Raft and Paxos prevent this by requiring a majority to agree on a leader; only one side of a partition can contain a majority. An old leader on the minority side may still think it is the leader for a short time, but it cannot get a majority to accept its writes.
For locks and leases, a common extra safeguard is a fencing token: a number that increases each time the lock is granted. The storage system rejects any request carrying an older token, so a client whose lease has expired cannot overwrite newer data. Martin Kleppmann described the technique in 2016, and Google's Chubby lock service uses a similar mechanism called sequencers.
GitHub's outage of 21 October 2018 shows what can go wrong. A loss of connectivity of 43 seconds between its US East Coast network hub and its main data centre led its failover tooling to promote database servers on the West Coast. Writes ended up in both places, and reconciling them took GitHub a little more than 24 hours of degraded service.
Testing with Jepsen
Jepsen, a project started by Kyle Kingsbury in 2013, tests distributed databases by cutting the network, skewing clocks and crashing nodes while a workload runs, then checking whether the results match the guarantees the database claims. Its analyses have found problems in many systems, including Redis Sentinel and early versions of MongoDB, and vendors often fix the issues it reports. The published analyses are one of the best public records of how databases behave during partitions.
CAP theorem in a system design interview
The CAP theorem comes up whenever a design replicates data across machines or data centres. Naming it is not enough; what an interviewer wants to hear is a decision for each kind of data and what it costs. A good answer:
- Treats partitions as given. The choice is between consistency and availability while the network is split, not “two of three”.
- Chooses per data type. Payments and inventory on a consistent store; carts, sessions, feeds and caches on an available one.
- Names the mechanism. Majority quorums or a consensus protocol such as Raft for CP; replication with conflict resolution (last writer wins, version vectors or CRDTs) for AP.
- Covers the normal case too. Synchronous replication across regions adds round trips to every write even with no partition. That is the latency side of PACELC.
- Says what happens on recovery. How diverged copies are merged, and which acknowledged writes can be lost.
CAP theorem questions and answers
What is the CAP theorem?
The CAP theorem says that a distributed data store cannot guarantee consistency, availability and partition tolerance at the same time. Because network failures cannot be ruled out, it is usually read as: when the network splits, a system must choose between consistency (refusing some requests) and availability (answering every request, possibly with out-of-date data). Eric Brewer proposed it in 2000, and Seth Gilbert and Nancy Lynch proved it in 2002.
Does CAP mean you can pick any two of the three properties?
No. Partition tolerance is not optional for a system that runs on more than one machine, because networks do fail. The choice applies only during a partition, and only between consistency and availability. When the network is working, a system can be both consistent and available.
What is an example of the CAP theorem?
Take a shopping cart and a lock service. Amazon’s Dynamo kept shopping carts writable during failures and merged diverging copies later, because refusing an “add to cart” costs more than an occasional duplicate item: an AP choice. A lock service such as etcd or ZooKeeper refuses requests on the minority side of a partition, because two clients both believing they hold the same lock is worse than a short outage: a CP choice.
Is consistency in CAP the same as consistency in ACID?
No. Consistency in CAP means linearizability: once a write completes, every later read sees it. Consistency in ACID means a transaction leaves the database in a valid state that satisfies its constraints. They are unrelated properties that share a word.
Is MongoDB CP or AP?
With its default settings MongoDB behaves as CP during a partition: only the side holding a majority of the replica set can elect a primary and accept writes. It is not strictly consistent in every configuration. Reads from secondaries can be stale, and writes acknowledged with write concern w: 1 can be rolled back after a failover. Since MongoDB 5.0 the default write concern is w: "majority", which avoids that rollback.
Is Cassandra CP or AP?
Cassandra is usually called AP, but the choice is made per request through the consistency level. With ONE, any reachable replica answers, so requests keep working during a partition and reads can be stale. With QUORUM, a request needs a majority of the replicas for that row and fails if it cannot reach them. For compare-and-set operations that must be linearizable, Cassandra has lightweight transactions, which use Paxos.
Is Redis CP or AP?
Neither, strictly. Redis replication is asynchronous, so a primary can acknowledge a write and then fail before a replica receives it, and the write is lost when the replica is promoted. The Redis Cluster documentation says it does not guarantee strong consistency. On the minority side of a partition, a Redis Cluster primary stops accepting writes after the node timeout, so it is not fully available either.
What is PACELC?
PACELC, proposed by Daniel Abadi, extends CAP: if there is a partition (P), a system trades availability against consistency (A or C); else (E), when the network is working, it trades latency against consistency (L or C), because keeping replicas in step means waiting for messages between them.
Is a single-server database CA?
It is sometimes called CA, because there is no network between replicas that could split. But if that one machine or its network connection fails, the database is simply unavailable. CA is only meaningful for systems that do not replicate across a network.
Further reading
- Gilbert and Lynch, 2002Brewer's Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web ServicesThe formal proof of the theorem.
- Brewer, 2012CAP Twelve Years Later: How the "Rules" Have ChangedBrewer's own look back, explaining why "two of three" is misleading.
- Abadi, 2012Consistency Tradeoffs in Modern Distributed Database System DesignThe article that introduced PACELC.
- Kleppmann, 2015Please stop calling databases CP or APWhy most real systems do not fit either label, and what to say instead.
- Kleppmann, 2015A Critique of the CAP TheoremA longer, more formal version of the same argument.
- Kleppmann, 2016How to do distributed lockingFencing tokens, and why a lock alone is not enough.
- Ongaro and Ousterhout, 2014In Search of an Understandable Consensus AlgorithmThe Raft paper. Raft is how etcd and Consul choose a single leader.
- GitHub, 2018October 21 post-incident analysisA detailed account of a real partition and the failover that followed.
- JepsenAnalysesTests of many databases under network partitions and other faults.
- JepsenConsistency modelsA map of linearizability, serializability and the weaker models.
- Kleppmann, 2017Designing Data-Intensive ApplicationsA book whose chapters on replication and consistency cover CAP in context.
- SemicolonyHow Raft consensus worksHow a cluster agrees on a leader and on the order of writes.