09-high-level-design

Latency, CAP Theorem, and Consistency Models

A practical guide to CAP theorem, PACELC, and consistency models, and how they drive real database and cache decisions.

August 14, 2026
backend-engineerlatencycap-theoremconsistencypacelcdistributed-systems

Latency, CAP Theorem, and Consistency

CAP theorem is one of the most cited — and most misquoted — ideas in distributed systems. Most engineers can recite "consistency, availability, partition tolerance, pick two," and almost none can explain what that actually constrains in a system they're operating. This guide gives you the accurate version of CAP, the consistency models it interacts with, the PACELC extension that fixes CAP's biggest blind spot (latency), and — most importantly — how these trade-offs actually show up when you're picking a database or designing a cache for a real service.


1. What CAP Actually Constrains

CAP theorem, formalized by Eric Brewer and later proven by Gilbert and Lynch, states that a distributed data store can provide at most two of the following three guarantees simultaneously, during a network partition:

  • Consistency (C) — every read receives the most recent write, or an error. This is linearizability, a strong guarantee — not the "C" in ACID.
  • Availability (A) — every request to a non-failing node receives a (non-error) response, without guarantee it's the most recent write.
  • Partition Tolerance (P) — the system continues to operate despite arbitrary network partitioning between nodes.
🚨

The most common misconception: "pick two of three, at all times." That framing is wrong. Partition tolerance is not optional in any real distributed system — networks will partition (a switch fails, a cable is cut, a node's NIC drops packets, cross-region latency spikes past a timeout). You cannot choose to opt out of network partitions, so in practice you are not choosing among C, A, and P freely. You are choosing between C and A, specifically during the partition window. A single-node system (no P) can trivially be both C and A — but then it isn't a distributed system, which defeats the reason you needed CAP in the first place.

CP vs AP in practice

System typeBehavior during partitionExample systemsUse when
CPMinority-side nodes refuse writes/reads rather than risk inconsistencyZooKeeper, etcd, HBase, MongoDB (default majority reads/writes)Config/coordination data, leader election, financial ledgers
APAll nodes keep serving, possibly stale/divergent data, reconciled laterCassandra, DynamoDB, Riak, CouchDBShopping carts, social feeds, session data, presence/status

Databases aren't purely CP or AP as a fixed label — most give you a dial. Cassandra and DynamoDB let you tune read/write quorum levels per operation (ONE, QUORUM, ALL), trading consistency for availability/latency on a per-query basis. MongoDB lets you choose read/write concern levels similarly. "What database is CP vs AP" is a useful first-pass mental model, but the accurate answer in a design interview is "it depends on the consistency level configured for this operation."


2. Consistency Models

"Consistency" is not binary. Distributed systems offer a spectrum of consistency models, each with different guarantees and different performance costs.

More guarantees, generally, cost more latency and availability. Fewer guarantees give you speed and resilience but push complexity onto the application.

Consistency models compared

ModelGuaranteeLatency costExample
Strong (linearizable)Reads always reflect the most recent completed write, globally, in real timeHighest — needs consensus/quorum on every operationBank balance read after transfer; leader-based config store
SequentialAll operations appear in some single global order, agreed by all nodes, but not necessarily matching real-time orderHighDistributed logs, some consensus systems
CausalIf operation B depends on (or was caused by) operation A, every node sees A before B; unrelated ops may appear in any orderModerateComment reply that must appear after its parent comment
Read-your-writesA client always sees its own prior writes, even if other clients don't yetModerate — often achieved via sticky routing or version tokensUser edits their profile, then reloads and expects to see the edit
Monotonic readsOnce a client has seen a value, it never sees an older value on a later readModeratePrevents a refresh from "going back in time"
EventualGiven no new writes, all replicas will converge to the same value — no bound on whenLowest — writes ack immediately, replicate asyncDNS propagation, social media like counts, CDN cache invalidation
💡

Read-your-writes and monotonic reads are the two most underrated models in practice. Pure eventual consistency without them produces a specific, jarring bug class: a user submits a form, the confirmation page reloads, and their own change appears to have vanished because the read landed on a replica that hasn't caught up yet. You can buy back this UX with cheap tricks — route a user's own reads to the primary for a short window after a write, or pass a "read-after" version token from the write response to subsequent reads — without paying for full strong consistency everywhere.

Real bug pattern: cache/DB consistency

⚠️

Cache invalidation races are a direct CAP/consistency trade-off, even in a "simple" cache-aside setup. Writing to the DB then deleting the cache key is two separate operations with no atomicity between them — a concurrent read can repopulate the cache with the stale value between your DB write and your cache delete. Mitigations: short TTLs as a backstop, write-through caching (update cache and DB together, harder to get right), or version-stamped cache entries that reject stale writebacks.


3. PACELC: The Extension CAP Doesn't Cover

CAP only describes trade-offs during a network partition. But partitions are rare; most of the time your system is running normally, and even then there's a trade-off between latency and consistency. PACELC, introduced by Daniel Abadi, makes this explicit:

If Partitioned: trade-off between Availability and Consistency; Else (normal operation): trade-off between Latency and Consistency.

This is a more honest model of real systems, because it captures the trade-off you're making every single request, not just during rare partition events. A system can be labeled with all four letters at once, e.g.:

SystemPACELC classificationMeaning
DynamoDB (eventually consistent reads)PA/ELPrioritizes availability during partitions, latency during normal ops
DynamoDB (strongly consistent reads)PA/ECSame availability choice, but pays consistency cost even when not partitioned
MongoDB (majority read/write concern)PC/ECPrioritizes consistency both during partitions and normal operation
Cassandra (QUORUM)PA/ECAvailable during partition, but normal-operation reads wait for quorum
Traditional single-primary RDBMS (sync replication)PC/ECStrong consistency always, at a latency cost on every write

PACELC is the more useful lens for day-to-day engineering decisions, because you spend 99.9%+ of your operational time in the "E" (normal, non-partitioned) branch. When you're picking read replicas, deciding whether to read from a follower, or setting a cache TTL, you're making an L-vs-C trade-off, not a CAP trade-off — even though people call it "the CAP decision" colloquially.


4. How This Shows Up in Real Backend Decisions

Choosing a database

Use caseRight consistency modelWhy
Bank account balance / ledgerStrongDouble-spending or lost transactions are unacceptable; correctness > availability
Inventory count at checkoutStrong (at least for the decrement operation)Overselling stock is a real business cost
Shopping cart contentsEventual, with read-your-writesLosing a cart item briefly is annoying, not catastrophic; but the user should see their own additions immediately
Social media like/view countersEventualExact real-time accuracy doesn't matter; approximate counts are fine
Leaderboard / real-time rankingCausal or bounded stalenessOrder relative to a user's own recent actions matters more than global real-time accuracy
Session/auth token validityStrong or bounded-staleness with short TTLA revoked token being honored for too long is a security bug
Search index / recommendationsEventualFreshness within minutes is acceptable; recomputing per-write is prohibitively expensive
Distributed lock / leader electionStrong (needs consensus: Raft/Paxos, ZooKeeper, etcd)Two nodes believing they're both leader is a correctness disaster
⚠️

A common design mistake: applying one consistency model uniformly across an entire service instead of per data type. A well-designed order system might use strong consistency for the payment/inventory decrement (via a transactional RDBMS) while using eventual consistency for the order-history read view and search index (via async replication to a document store). Treat consistency as a property you choose per data type, not a single global architectural stance.

Latency budget example: synchronous replication cost

text
Single-region write, no replication ack required:      ~2ms  (local disk fsync)
Synchronous replication to 1 same-region replica:      ~2-5ms  (extra network round trip)
Synchronous quorum write across 3 AZs (same region):    ~5-15ms (round trip to majority)
Synchronous write requiring cross-region quorum:        ~50-150ms (WAN round trip)

This is the concrete cost of buying stronger consistency: every additional round trip you require before acknowledging a write is latency the client waits on. A cross-region synchronously-consistent write is often 10-50x slower than a local, asynchronously-replicated one — which is exactly why globally distributed systems lean AP/eventual for most data and reserve synchronous cross-region consensus for the handful of operations (leader election, critical financial state) that truly require it.


5. Common CAP Misconceptions

Because CAP gets summarized in a soundbite so often, it accumulates myths. Being able to correct these precisely is one of the fastest ways to signal real distributed-systems understanding in an interview.

MisconceptionWhy it's wrongThe accurate version
"You can choose any two of C, A, P"Partition tolerance isn't a design choice in a real multi-node system — the network will partition regardless of what you'd preferYou choose between C and A, and only during an actual partition; outside a partition, both are achievable simultaneously
"A CP system is always consistent"CP only describes behavior during a partition; consistency also depends on the actual consistency level configured for each read/writeA "CP" database can still serve stale reads if you configure a weaker read concern — the label describes a default posture, not an absolute guarantee
"CAP applies to single-node databases"CAP is a theorem about distributed systems with multiple nodes replicating dataA single-node Postgres instance isn't subject to CAP at all — there's nothing to partition. CAP only becomes relevant once you replicate or shard
"NoSQL means eventually consistent, SQL means strongly consistent"Consistency is an architectural choice, not a property of the query languageMongoDB, Cassandra, and DynamoDB all offer tunable consistency levels; distributed SQL systems (CockroachDB, Spanner) offer strong consistency at global scale
"ACID and CAP's 'C' mean the same thing"ACID's Consistency means the database moves between valid states per its own constraints (e.g., foreign keys, check constraints); CAP's Consistency means linearizability across replicasA single-node ACID database can be perfectly ACID-consistent while the CAP consistency question doesn't even apply, since there's no replication
"Eventual consistency means the system is unreliable"Eventual consistency is a deliberate trade for availability and latency, not a defectEventually consistent systems can have extremely well-defined, bounded convergence behavior — "eventual" is a spec, not an excuse
⚠️

The ACID-"C" vs CAP-"C" collision is a genuine interview trap. When someone says "our Postgres database is consistent," they usually mean ACID consistency (constraints hold). When CAP theorem says "consistency," it means linearizability across replicas of that data. These are different properties that happen to share a letter. A single-node database can be fully ACID-consistent and have no CAP consistency question at all, because CAP only applies once you have more than one node holding a copy of the data.


6. Production Observations

  • "Eventual consistency" without a consistency window is an incomplete spec. "Eventually" could mean 10 milliseconds or 10 minutes depending on replication lag under load. When you design with an AP store, state the expected replication lag as an SLO and monitor it — unbounded staleness is a silent correctness bug waiting to happen during a traffic spike or partial outage.
  • Read replicas are a latency/consistency trade-off you make constantly, even in a boring single-region RDBMS setup. Reading from a replica to reduce primary load means accepting replication lag; a SELECT immediately after a related INSERT can miss the row if routed to a lagging replica.
  • Idempotency keys are how you make AP systems safe for writes that must not duplicate (e.g., payment charges). Since AP systems favor availability under partition, a client may retry a write it's unsure succeeded — an idempotency key lets the server safely dedupe that retry instead of double-processing it.
  • Distributed locks need a consensus-backed store, not a cache. Using Redis alone for a distributed lock without care for its failure modes (e.g., a primary failover losing an unreplicated lock) can produce two clients both believing they hold the lock. Redlock and similar algorithms exist to address this, and for genuinely critical locks (leader election), a CP system like ZooKeeper or etcd is the more defensible choice in a design interview.
  • Vector clocks and version vectors are how AP systems detect conflicting concurrent writes without a central arbiter — worth naming if asked how Dynamo-style systems resolve divergent replicas (last-write-wins is the simpler but lossier alternative).
  • Clock skew is a hidden tax on any timestamp-based consistency scheme. "Last write wins" using wall-clock timestamps assumes synchronized clocks across nodes; NTP drift of even tens of milliseconds can cause an actually-later write to lose to an actually-earlier one. Logical clocks (Lamport timestamps, vector clocks) sidestep this by tracking causality instead of wall-clock time.

Key takeaways

  • CAP is not "pick two of three" — partition tolerance isn't optional in a real distributed system, so the actual choice is C vs A during a partition.
  • Consistency is a spectrum (strong, sequential, causal, read-your-writes, monotonic, eventual), not a binary; pick the weakest model that's still correct for the data in question.
  • PACELC captures the trade-off CAP misses: even with no partition, you trade latency for consistency on every request.
  • Apply consistency choices per data type within a system, not as one global architectural stance — payment state and view counters have very different needs.
  • Every synchronous replication hop you add to satisfy stronger consistency is a direct, measurable latency cost — quantify it before committing to it.
  • Idempotency keys, version tokens, and short-TTL sticky reads are cheap, practical tools for buying back the UX cost of eventual consistency without paying for full strong consistency.
  • "Eventually consistent" needs a bounded, monitored replication-lag SLO — otherwise it's an unbounded promise, not a design decision.

Interview Questions

  • Explain CAP theorem accurately. Why is "pick two of three" a misleading way to state it?
  • What is the difference between a CP and an AP system? Give a real database example of each and describe its behavior during a partition.
  • What is PACELC, and why does it describe real-world trade-offs better than CAP alone?
  • Define strong, causal, and eventual consistency. Order them by both guarantee strength and latency cost.
  • What is "read-your-writes" consistency, and why does its absence cause a specific, user-visible bug? How would you fix it without going fully strongly consistent?
  • Walk through a cache-aside pattern (update DB, then invalidate cache) and explain the race condition that can leave the cache stale.
  • You're designing a shopping cart service and an account balance service in the same system. Would you use the same consistency model for both? Why or why not?
  • How does synchronous cross-region replication affect write latency? Give rough relative numbers for local vs. same-region-multi-AZ vs. cross-region writes.
  • Why do distributed locks typically require a CP system (like etcd or ZooKeeper) rather than a plain cache?
  • What problem do idempotency keys solve in an eventually-consistent or at-least-once-delivery system?
  • What is clock skew, and why can it break naive "last write wins" conflict resolution? What's an alternative?
  • If a read replica is lagging behind the primary, what specific bugs can that cause for a user who just wrote data?
  • How would you classify DynamoDB and a traditional single-primary RDBMS with synchronous replication under the PACELC model?
  • What monitoring would you put in place to catch an AP system's "eventual" consistency window silently growing during a traffic spike?