The CAP Theorem and Consistency Models, Without the Folklore
- system-design
- distributed-systems
- concurrency
- databases
- architecture
The CAP theorem is the most cited and most misunderstood idea in distributed systems. People invoke it to justify choices it does not actually govern, and repeat the "pick two of three" slogan without noticing that one of the three is not really optional. Once you strip away the folklore, CAP is a genuinely useful lens — but only if you understand what it actually says and, just as important, what it does not.
This is a practical look at CAP, the consistency models that sit underneath it, and how to decide how much consistency each part of your system actually needs. It connects directly to database-level concurrency questions like isolation levels and ACID transactions, which are where these abstract ideas become concrete code.
What CAP actually says
CAP concerns a system that keeps data on more than one machine. It names three properties:
- Consistency: every read sees the most recent write. All nodes agree on the current value.
- Availability: every request gets a response, without error, even if some nodes are down.
- Partition tolerance: the system keeps working even when the network between nodes is broken and messages are lost.
The theorem says you cannot have all three at once. The popular framing is "pick two," and that framing is where the confusion starts.
Partition tolerance is not optional
Here is the part the slogan gets wrong. In any real distributed system, network partitions will happen. Networks drop packets, links fail, switches reboot. You do not get to choose whether partitions occur; you only get to choose how your system behaves when one does. That means partition tolerance is not one of three equal options — it is a requirement. The real choice is a binary one that only appears during a partition: when the network splits, do you favor consistency or availability?
- Choose consistency (a CP system) and, during a partition, the system refuses requests it cannot serve correctly rather than risk returning stale or conflicting data. Some requests fail, but no one reads a wrong value.
- Choose availability (an AP system) and, during a partition, the system keeps answering on both sides of the split, accepting that the two sides may temporarily disagree and will have to reconcile later.
That is the actual decision CAP describes. Not "pick two of three" in the abstract, but "when the network breaks, do you sacrifice serving some requests, or do you sacrifice everyone agreeing on the answer?" When the network is healthy — which is almost all the time — you get both consistency and availability. CAP only bites during the partition.
PACELC: the part CAP leaves out
CAP only talks about behavior during a partition, which leaves out the vastly more common case: the network is fine, so what then? PACELC extends CAP to cover it. It reads: if there is a Partition, choose between Availability and Consistency; Else (normal operation), choose between Latency and Consistency.
That second clause is the one that shapes daily performance. Even with a healthy network, strong consistency has a cost. To guarantee that every read sees the latest write, nodes have to coordinate — confirm with each other before responding — and coordination takes time. So there is a constant trade-off between consistency and latency that exists whether or not anything is broken. A system that insists on strong consistency pays for it in slower reads and writes every single day, not just during failures. PACELC makes that ongoing tax visible in a way CAP does not.
The consistency models
"Consistency" is not one thing; it is a spectrum, and knowing where you are on it matters more than the CAP label.
Strong consistency means once a write completes, every subsequent read anywhere returns that value. The system behaves as if there were a single copy of the data. This is the easiest model to reason about and the most expensive to provide, because it requires coordination on every operation.
Eventual consistency means if writes stop, all copies will eventually converge to the same value, but for some window after a write, different reads may see different values. This is much cheaper and more available, and for a great deal of data it is completely fine. A follower count that is a second or two stale harms nothing.
Between those extremes sit models worth knowing by name, because they capture what applications usually actually need:
- Read-your-own-writes: you always see your own updates immediately, even if others see them slightly later. This is what prevents the "I saved it but it still shows the old value" bug that plagues systems with read replicas.
- Monotonic reads: once you have seen a value, you never see an older one afterward. Time does not appear to run backward for a given user.
- Causal consistency: operations that are causally related (a reply after the message it answers) are seen in the right order everywhere, even if unrelated operations are not.
These middle models are often exactly the sweet spot: far cheaper than global strong consistency, but strong enough that users never notice anything wrong.
Choosing consistency per piece of data
The practical mistake is treating consistency as a single global setting. Real systems need different guarantees for different data, and the skill is matching the guarantee to the cost of being wrong.
Ask what happens if a reader sees a slightly stale value. For a like count, a product view total, or a list of recent articles, the answer is "nothing meaningful," so eventual consistency is the right, cheap, available choice. For an account balance during a purchase, a seat being booked, or inventory being decremented, a stale read can double-spend money or oversell a product, so you need strong consistency and you pay for it willingly, usually inside a database transaction with an appropriate isolation level.
Most systems end up as a deliberate mix: strong consistency around money, identity, and anything with a uniqueness constraint, and eventual consistency almost everywhere else. Getting this split right is what lets a system be both fast and correct, because it spends its expensive consistency budget only where correctness genuinely demands it.
The takeaway
CAP is not a menu you order two items from. Partitions are a fact, so the real question is how you behave when one happens, and PACELC reminds you that consistency costs latency even when nothing is broken. Underneath both, consistency is a spectrum, and mature systems place each piece of data on it according to how much a stale read would actually cost. That per-data judgment — cheap and available where staleness is harmless, strong and coordinated where it is not — is the heart of the trade-off reasoning the system design framework is built around.
Key takeaways
- Partition tolerance is not optional — networks fail regardless — so CAP's real choice appears only during a partition: favor consistency or availability.
- When the network is healthy you get both consistency and availability; CAP only bites during a partition.
- PACELC adds the everyday case: even with no partition, strong consistency costs latency because nodes must coordinate.
- Consistency is a spectrum from strong to eventual, with useful middle models like read-your-own-writes, monotonic reads, and causal consistency.
- Choose consistency per piece of data: eventual where staleness is harmless, strong where a stale read costs money or correctness.
Frequently asked questions
What does the CAP theorem actually say?
That a system keeping data on multiple machines cannot simultaneously guarantee consistency (every read sees the latest write), availability (every request gets a response), and partition tolerance (it keeps working when the network splits). Since partitions are unavoidable, the real choice is between consistency and availability during a partition.
Why is "pick two of three" misleading?
Because partition tolerance is not a free choice — real networks partition whether you like it or not. You cannot opt out of it, so the genuine decision is a binary one that only appears during a partition: do you sacrifice serving some requests (consistency) or everyone agreeing on the answer (availability)?
What is PACELC?
An extension of CAP: if there is a Partition, choose between Availability and Consistency; Else, in normal operation, choose between Latency and Consistency. It captures that strong consistency costs latency every day through coordination, not only during failures.
What is the difference between strong and eventual consistency?
Strong consistency means every read sees the latest write immediately, as if there were one copy — easy to reason about, expensive to provide. Eventual consistency means copies converge over time, so reads can briefly differ — cheaper and more available, and fine for data like counts or feeds where slight staleness is harmless.
Further reading
Explore more on

About the author
I'm Aman Kumar Singh, a software engineer in Noida, India building scalable full-stack products with React, Next.js, Node.js, NestJS, PostgreSQL, Redis, and AWS. I write about backend engineering, distributed systems, and system design.