If you remember five things
A consistency model is a contract about what a read can see after a write. These five decide the whole conversation.
- It is a spectrum, not two buckets. Strong, causal, read-your-writes, and eventual sit on a line from most coordination (most expensive) to least.
- It is per operation path, not per database. The same table can give eventual reads by default and strong reads when you ask and pay for them. You choose per read.
- Strong consistency is coordination. A write waits for a quorum to agree before it commits. That wait is latency you pay on every write, and across regions it is brutal.
- PACELC beats CAP. Partitions are rare, so the honest tax is the Else clause: even when healthy you trade Latency against Consistency on every single operation.
- Default weak, strengthen on purpose. Pick the weakest model the data can tolerate, then upgrade the few paths (money, inventory, locks) that genuinely need it.
1The core idea#
Start with why this problem exists at all, because the origin tells you everything.
- One copy of your data means consistency is free. There is one truth, everyone reads it, done.
- Consistency becomes a problem only because you made copies: replicas for availability, caches for speed, read replicas for scale.
- So a consistency model is the price you pay back for every copy you added.
A consistency model is a contract. It tells the client what the system promises about the order and timing of reads relative to writes. Nothing more mystical than that.
Think of it as a spectrum. Four points on one line, from most coordination to least:
- Strong (linearizable). Once a write finishes, every later read anywhere in the world sees it. The system behaves as if there is a single copy and operations happen in one global order. Easiest to reason about, most expensive to provide.
- Sequential / causal. Weaker. Everyone agrees on an order, or at least on cause-and-effect order, but it might not match wall-clock time.
- Eventual. The weakest useful promise. If writes stop, all replicas converge to the same value eventually. Could be 10 milliseconds. Could be 30 seconds during a partition. No guarantee about what you read in the meantime.
Consistency is not a property of your database brand. It is a property of each operation path. The same DynamoDB table gives you eventual reads by default and strongly consistent reads if you ask (and pay double the read capacity: 1 RCU per 4 KB strongly consistent vs 0.5 RCU eventually consistent). You choose per read, not per database.
2How it works#
The whole mechanism reduces to one idea: strong consistency costs you a round of coordination before a write is acknowledged. That is the game.
Quorums make the trade-off concrete. Take 3 replicas and pick W (replicas that must ack a write) and R (replicas you read from):
- If
W + R > N, your read set and write set always overlap by at least one replica, so a read is guaranteed to touch a node that has the latest write. - With N=3, W=2, R=2, any read hits a node that saw the last committed write. That overlap is where strong-ish consistency comes from.
- Set W=1, R=1 and you get fast, available, eventually consistent writes. No overlap guarantee: a read can land on a replica that has not received the write yet.
A strong write waits for the quorum. The leader holds the client until enough replicas agree:
Eventual consistency flips it. The leader acks immediately and gossips the change out in the background:
Causal consistency sits in the useful middle. It enforces order only between operations that actually depend on each other:
- Post a comment, then reply to it: every replica must show the comment before the reply, because the reply causally depends on the comment.
- Two unrelated posts from different users can show up in any order.
- Systems track this with version vectors or Lamport-style logical clocks that stamp each write with "what did the writer know when they wrote this."
Client-centric guarantees are the ones that save you in product work. They are cheap and they kill real bugs:
- Read-your-writes. After I change my profile photo, I see the new photo immediately, even if others see the old one for a few seconds. Usually done by pinning my session to the replica I wrote to, or routing my reads to the leader for a short window.
- Monotonic reads. Once I have seen a newer value, I never see an older one. No time travel backward. Prevents the maddening bug where refreshing shows a comment, then it vanishes, then comes back.
A worked example: one write, three regions, real numbers#
This is the part that separates a label-dropper from someone who has done the math. Run N=3 replicas, one each in us-east-1, eu-west-1, and ap-south-1. Round-trip latencies between them, roughly what real AWS inter-region links show:
- us-east-1 to eu-west-1: about 80 ms
- us-east-1 to ap-south-1: about 190 ms
- eu-west-1 to ap-south-1: about 120 ms
A user in Virginia writes balance = $100 through the us-east-1 leader. Walk the two policies.
Strong, W=2 (majority quorum).
- Leader writes locally (about 1 ms) and fires replication to both peers in parallel.
- It needs one more ack to hit W=2. eu-west-1 answers first at about 80 ms round trip; ap-south-1 would not answer until about 190 ms.
- Leader commits the instant the eu-west ack lands and tells the client "done" at roughly 81 ms.
- The guarantee: because R + W > N (R=2, W=2, N=3), any later read touching 2 replicas hits at least one that saw
$100. A Mumbai user reading immediately with R=2 sees the correct$100, even though ap-south-1's own copy is still catching up.
Eventual, W=1.
- Leader writes locally and acks the client in about 1 ms. Great for the Virginia user.
- Replication to Mumbai is async and completes at about 190 ms.
- A Mumbai user reading their local ap-south-1 replica at the 50 ms mark sees the old balance.
- That is a 190 ms staleness window per write on that path, and it widens to seconds if the ap-south link is congested or partitioned.
3Trade-offs#
This is where interviews are won. The tension comes from CAP and its more honest cousin PACELC.
PACELC is the version to carry into the room.
- During a network Partition you choose Availability or Consistency.
- Else (normal operation) you still trade Latency against Consistency.
- That second half matters more day to day. Partitions are rare. The latency tax on strong consistency is paid every millisecond you are up, as the worked example showed.
| Model | Read latency | Write latency | Availability during partition | Reasoning difficulty | Good for |
|---|---|---|---|---|---|
| Strong / linearizable | High (coordination) | High | Low (may reject writes) | Easy | Money, inventory, locks, config |
| Causal | Medium | Medium | High | Medium | Social feeds, comments, collaboration |
| Read-your-writes | Low | Low | High | Medium | Profiles, settings, user-owned data |
| Eventual | Lowest | Lowest | Highest | Hard | Likes, view counts, caches, DNS |
What you give up, concretely:
- Choosing strong. You give up availability and low latency. If a quorum is unreachable, writes stall or fail. Users in a partitioned region get errors. Cross-region writes feel slow: the 81 ms from above instead of 1 ms.
- Choosing eventual. You give up predictable reads and inherit conflicts: two replicas accepting different writes to the same key. Someone has to resolve them with last-writer-wins (simple, silently loses data), CRDTs (correct, more complex), or application merge logic (a shopping cart that unions items so nothing ever disappears).
Reveal the answer
My opinionated take, and the one I want to hear back: default to the weakest model your product can tolerate, then strengthen the specific paths that genuinely need it. A like counter off by 3 for two seconds has never cost anyone money. An account balance wrong by $3 for two seconds absolutely has. Blanket "we'll use strong consistency" tells me you never costed it.
4Where it is used#
Name real systems. It proves you have seen these choices land in production.
- Strong. Google Spanner (synchronized clocks via the TrueTime API give global linearizable transactions, which is why it needs atomic clocks and GPS in datacenters). etcd and ZooKeeper for cluster config and leader election, because two nodes both thinking they are leader is a disaster. Postgres on a single primary. Anything touching payments.
- Eventual. DNS, the classic example: propagation takes minutes and nobody dies. Amazon's original Dynamo paper and its shopping cart. S3 was eventually consistent for years (it became strongly consistent for reads in 2020, which was a big deal). CDN caches. Redis replicas used for read scaling.
- Causal / client-centric. Collaborative editors, comment threads, and messaging apps where message order within a conversation must hold. MongoDB offers causal consistency within a session. Cassandra and DynamoDB let you dial R and W per operation.
When would I reach for each?
- Seat booking or ticketing: strong consistency on the "is this seat taken" check, because double-booking is a real refund and an angry customer.
- News feed or notification count: eventual is fine, and the latency win is worth it.
- "Edit your own settings": read-your-writes is the sweet spot. Cheap, and it kills the number-one user complaint ("I saved it but it didn't save").
5Common pitfalls and gotchas#
Each of these is a place I have watched a real design quietly break.
- Assuming your database is one thing. It is a pipeline. Primary is strong, read replicas are eventual, Redis is its own staleness window, the CDN is another. A write can be committed and still invisible to a user whose read hit the cache. Trace the full read path.
- Forgetting the cache is a replica. Adding a cache silently downgrades your consistency. Your TTL is your staleness bound. A 60-second TTL means you promised nothing stronger than "60 seconds eventual" no matter how strong your database is.
- Last-writer-wins eating data. LWW keeps the write with the latest timestamp. Clean, but it silently throws away the other write. Two users edit the same doc, one edit just vanishes. If data loss matters, you need CRDTs or explicit merge.
- Clock skew. LWW and many ordering schemes lean on timestamps. Machine clocks drift, often tens of milliseconds between hosts without discipline. Without NTP correction or logical clocks, "latest" is a lie and you get subtle, unreproducible bugs.
- Read-your-writes breaking on failover. You pinned the user to the replica they wrote to, that replica died, and they got rerouted to one that had not caught up. Now their own write disappears. Session stickiness needs a fallback plan.
- Confusing consistency with durability and isolation. Durability is "did the write survive a crash." Isolation (the I in ACID) is about concurrent transactions. Consistency here is about replica agreement. Keep these straight: most candidates blur them, and interviewers notice when you do not.
6How it shows up in interviews#
Interviewers rarely ask "define linearizability." They slip it into a design.
- They say "now we have users in three regions" or "add a read replica to handle the load."
- Then they watch whether you notice you just changed the consistency guarantee.
What they probe:
- Can you map a specific piece of data to a specific model and justify it? Blanket "we'll use strong consistency" is weak. It says you did not think about cost.
- Do you know the mechanism, not just the label? If you say strong, can you explain the quorum or leader coordination that provides it, and name the latency it adds (like the 81 ms cross-region quorum)?
- Do you handle the failure case? What happens during a partition? What resolves a write conflict?
The difference between a weak answer and a strong one is not vocabulary. It is specificity: name the data, the model, the mechanism, a latency number, and the partition behavior.
"I'll use a strongly consistent database so there are no bugs." This ignores latency, availability, and cost, treats the database as a single magic box, and silently pays the 81 ms cross-region tax on every write, including the 90% of data (likes, feeds, view counts) that never needed it. The interviewer hears "has not run this in production."
Strong answer, for contrast: "The account balance and the transfer need linearizability, so I keep those in single-primary Postgres with synchronous replication and eat the write latency, roughly 80 ms if the quorum spans regions. The transaction history feed can be eventually consistent and served from read replicas, since showing a transaction half a second late is fine. For the user's own profile edits, read-your-writes via session pinning feels snappy without paying for global strong consistency. During a partition I would rather reject writes to the balance than risk a double-spend, so that path is CP; the feed stays available and is AP. And since I just added that read replica for the feed, that path is now eventually consistent with a staleness window equal to replication lag, which is fine here."
When you add any replica or cache, say out loud: "note this makes this read path eventually consistent, here is the staleness bound, here is why it is acceptable." Interviewers remember the candidate who caught the consistency implication unprompted, because that is the exact instinct that prevents the bug in production.
"You said W=2, R=2, N=3. Walk me through why that gives a correct read."
"I add a read replica to scale reads. What just changed?"
"Two users write the same key on two replicas during a partition. How do you resolve it?"
"My read-your-writes session pinning breaks on failover. Why, and what is the fix?"
"Is Spanner strong consistency free, then? Global transactions with no catch?"
What you can now explain in the room
- Why copies are the only reason consistency is ever a problem, and why the model is a per-operation contract.
- How a quorum with W + R > N gives you a read that is guaranteed to see the latest write.
- The real cost of strong consistency in numbers: an 81 ms cross-region commit versus a 1 ms eventual ack.
- Why PACELC is the more honest framing than CAP for everyday operation.
- How a cache or read replica silently downgrades a strong database to eventual, bounded by TTL or replication lag.
- How to answer a design prompt by naming the data, the model, the mechanism, a latency number, and the partition behavior.
Next, try the system design question walkthrough on designing a distributed key-value store, where picking R, W, and N per workload is the entire problem.
Get a prep plan built around your Consistency Models interview
Tell us the role and your interview date. We will send back a dated, day by day plan. Free.