On this page
Description
Whenever a system keeps copies of its data on more than one machine, it has to decide what happens when those copies can't talk to each other - and what "up to date" means the rest of the time. This lesson is about that decision: the CAP theorem, the consistency models you can choose from, and the quorum arithmetic behind many databases.
Picture a concert-ticket site that keeps its seat data in two data centers, one in Virginia and one in Dublin. One evening the link between them drops for 90 seconds. Two fans, one on each side of the Atlantic, click "Buy" on seat 14C at the same moment.
The site has two honest options:
- Let both purchases go through. Both fans get a confirmation email, and you've sold one seat twice. Someone gets turned away at the door.
- Refuse sales on one side until the link is back. Fans there see an error page for a minute and a half.
There's no third option that keeps every request working and never double-sells. That trade-off has a name, the CAP theorem, and every system that keeps copies of its data on more than one machine runs into it. You either choose how to handle it, or you find out what you chose during an outage.
In this lesson:
- CAP in plain words, and why "pick two" is misleading.
- PACELC - the trade-off you pay on every request, not just during outages.
- Consistency models, from strongest to weakest, and matching them to features.
- Quorums: when reads are guaranteed to see the latest write.
- What to do when copies disagree.
CAP in plain words
CAP talks about three properties of a system that keeps copies (replicas) of its data on different machines:
- Consistency (C): every read sees the most recent write, as if there were only one copy. The formal name is linearizability.
- Availability (A): every request that reaches a working machine gets a real answer, not an error.
- Partition tolerance (P): the system keeps running when the network splits it into groups that can't talk to each other.
You'll often hear "pick two of the three". That's misleading. Networks do split: cables get cut, switches fail, a cloud region has a bad day. So partition tolerance isn't something you get to skip. The real question is what your system does during a split:
- CP (consistent): refuse or delay the requests it can't answer safely. etcd, ZooKeeper, and a single-leader database that rejects writes on the side without the leader all work this way.
- AP (available): answer from whatever copy it can reach, and sort out disagreements later. Cassandra and DynamoDB behave this way in their default settings.
Read more - what about "CA" systems?
A "CA" system is one that can't survive a network split, which really means it isn't distributed: a single database server, for example. It's consistent and available right up until its one machine or its network fails. That's a perfectly good design for many products, but it's not an answer to the CAP question.
The everyday trade-off: PACELC
Network splits are rare. Latency is with you on every single request. PACELC adds that second half: if there's a Partition, choose Availability or Consistency; Else, choose Latency or Consistency.
Here's why. To be strongly consistent, a write has to reach a majority of copies before you tell the user "saved". If those copies live in different regions, that's a round trip across an ocean on every write. Most databases therefore let you choose per request. A checkout can pay for a strongly consistent read of the stock count. A product page can show a count that's a second old.
Consistency models, from strongest to weakest
| Model | What it promises | Good for |
|---|---|---|
| Linearizable (strong) | Every read sees the latest write | Unique usernames, seat reservations, account balances, locks |
| Causal | If one write caused another, everyone sees them in that order | Comments and the replies to them |
| Read-your-writes, monotonic reads | You see your own changes, and you never jump back in time | Editing your profile, your own posts |
| Eventual | Copies agree once writes stop | Like counts, view counters, recommendations |
The key skill is matching the model to the feature, not to the whole system. One social app can keep usernames strongly consistent and like counts eventually consistent, side by side. Paying for strong consistency everywhere makes everything slower. Skipping it where it matters double-sells seats.
Read more - read-your-writes in practice
A common way to give users read-your-writes on top of lagging read replicas: for a few seconds after a user changes something, send that user's reads to the leader (or to a replica that has caught up past their write). Everyone else keeps reading from replicas. The user never sees their own edit vanish, and the leader isn't flooded.
Quorums: overlapping reads and writes
Many replicated stores keep each item on N machines. A write counts as done once W of them confirm it. A read asks R of them and keeps the newest version it gets back.
The rule to remember: if R + W > N, every read overlaps every acknowledged write in at least one machine. That overlapping machine has the latest value, so the read sees it.
For N = 3:
| W | R | R + W > N? | What you get |
|---|---|---|---|
| 2 | 2 | Yes | Balanced. Reads and writes both survive one copy being down |
| 3 | 1 | Yes | Fast reads, but if any copy is down, writes stop |
| 1 | 3 | Yes | Fast writes, but if any copy is down, reads stop |
| 1 | 1 | No | Fastest, and reads may be stale |
Quorums make stale reads much rarer, but they don't make a system linearizable on their own: two writes can race, and some stores accept writes on stand-in machines during failures. When you truly need "only one person gets seat 14C", use a store built on a consensus protocol such as Raft, which runs every write through an elected leader and a majority vote.
When copies disagree
In an AP system, two copies can accept different writes for the same item during a split, or two users can edit the same record at the same moment. Something has to decide what the final value is.
- Last write wins (LWW): keep the write with the later timestamp. It's simple, and it silently throws the other write away. Server clocks drift, so it can even throw away the write that really came last.
- Keep both and merge: store versions (vector clocks) and merge them in the application, the way a shopping cart can combine items added on two devices.
- Use data types that merge themselves (CRDTs): counters, sets and similar structures designed so that any two copies combine to the same answer.
- Avoid the conflict: send all writes for one item to a single leader, so there's never more than one opinion.
Which to use when
| Situation | Reach for |
|---|---|
| Money, inventory, unique names, locks | A strongly consistent store (single leader with synchronous replication, or a consensus-based store) |
| A user must see their own change immediately | Read-your-writes: read from the leader for that user for a short while |
| Counters, likes, views, analytics | Eventual consistency, ideally with CRDT counters |
| Global users, writes from many regions | An AP store with conflict resolution, or a leader per item (home region) |
| An interview question that says "highly available" | Say what is allowed to be stale and for how long, then pick the model per feature |
Common mistakes
- "We'll pick CA." Not an option for a distributed system: say what happens during a split instead.
- Strong consistency everywhere. It costs latency on every request and availability during failures. Use it where a stale answer breaks a promise.
- Trusting last-write-wins with data people care about. It loses writes quietly, and clock drift makes it worse.
- Forgetting the user's own view. Eventual consistency is fine for others' likes, and jarring when your own comment disappears after a refresh.
Check yourself
Try to answer before opening each one - recalling beats re-reading.
1. Why is "choose two of C, A and P" misleading?
Show answer
A distributed system can't opt out of network splits. The real choice is what to do during one: stay consistent by refusing some requests, or stay available and risk stale or conflicting answers.
2. N = 5 and W = 3. What's the smallest R that guarantees a read sees the latest acknowledged write?
Show answer
R = 3, because R + W must be more than N: 3 + 3 = 6 > 5. With R = 2, you get 2 + 3 = 5, and a read could land only on the two copies that missed the write.
3. Which parts of a shopping site need strong consistency?
Show answer
Anything where two different answers break a promise: stock at checkout (don't oversell), payments, and one-time coupon codes. Reviews, view counts and recommendations can be eventually consistent.
Key takeaways
- During a network split, a replicated system either refuses some requests (consistent) or risks stale answers (available).
- PACELC: even without a split, strong consistency costs latency.
- Choose the consistency model per feature: strong for money and uniqueness, eventual for counters.
- Quorums: R + W > N makes every read overlap the latest write; W = N gives up write availability.
- Last-write-wins quietly loses data. Merge, use CRDTs, or send each item's writes to one leader.