Skip to content

Consistency models and the CAP theorem

Senior

What CAP actually constrains, strong vs eventual vs causal consistency, and why most real systems live somewhere in between.

Created 4 September 2026 · Updated 12 September 2026

7 concepts · detail hidden

  1. 01The CAP theorem — what it actually forces, and the common misreading

    For a distributed system, during a network partition (P — some nodes cannot communicate with others, which real networks will eventually experience), you must choose between Consistency (every read sees the most recent write, or an error) and Availability (every request receives a non-error response, even if it might not be the most recent data). You cannot have both during the partition. The most common misreading: treating CAP as “pick 2 of 3 permanently” — Partition tolerance is not optional for any real distributed system spanning more than one node/network segment, so the actual choice is CP vs AP, and only during an active partition; when the network is healthy (the common case), a well-designed system can be both consistent and available simultaneously. CAP says nothing about latency or normal-operation trade-offs — that gap is what the PACELC extension addresses.

    #c-the-cap-theorem-what-it-actually-forces-and-the-common-misre
  2. 02What PACELC adds to CAP, and why it matters more day to day

    PACELC: if there is a Partition, choose between Availability and Consistency (this is plain CAP); Else (no partition, normal operation), choose between Latency and Consistency. This matters more day-to-day because partitions are relatively rare events, while the latency/consistency trade-off during normal operation is active on every single request: a system that always reads from a strongly-consistent source (e.g. always the primary, or a quorum) pays a real, constant latency cost even when nothing is wrong, versus one that allows reading from a nearby replica that might be milliseconds-to-seconds stale for lower, more predictable latency. Most real architecture decisions (read replicas, caching, geo-distributed reads) are actually PACELC trade-offs made during healthy operation, not CAP trade-offs made during a rare partition — which is why PACELC is the more practically useful framing when reasoning about a concrete system.

    #c-what-pacelc-adds-to-cap-and-why-it-matters-more-day-to-day
  3. 03Strong vs eventual vs causal consistency — definitions and where each fits
    • Strong consistency — every read reflects the most recent completed write, as if there were only one copy of the data. Right when correctness depends on it directly — a bank balance check before approving a withdrawal, a seat reservation system where double-booking is unacceptable.
    • Eventual consistency — replicas will converge to the same value eventually, with no bound on how long “eventually” takes under adverse conditions, but reads in between can return stale or differing values across replicas. Right when brief staleness is harmless and availability/latency matter more — a social media like-count, a product view counter, most caches.
    • Causal consistency — a middle ground: writes that are causally related (a reply to a comment, an edit that depends on reading a prior value) are seen by every observer in that same causal order, but causally-unrelated writes can be observed in different orders by different replicas. Right when full strong consistency is too expensive but “eventual, with no ordering guarantee at all” would produce visibly nonsensical results — e.g. a comment thread must never show a reply before the comment it replies to, even if unrelated comments elsewhere can appear in any order across users.
    #c-strong-vs-eventual-vs-causal-consistency-definitions-and-whe
  4. 04Why strong consistency has an unavoidable latency cost across regions

    Guaranteeing every reader sees the latest write means a write (or a read that must be certifiably current) cannot be considered complete until enough replicas — often a quorum, or in single-leader systems the leader itself plus any synchronously-replicated followers — have durably applied it, and that requires a round trip across whatever network distance separates those nodes. If replicas are spread across regions, that round trip is bounded below by the speed of light over the physical distance, not by anything you can optimize away with better code — a cross-continent quorum write is fundamentally slower than a same-datacenter one, full stop. This is why globally strongly-consistent systems (e.g. Spanner-style designs) invest heavily in specialized infrastructure (tightly synchronized clocks, careful quorum placement) to push that latency floor as low as physically possible, rather than eliminating the trade-off — and why many systems instead choose to relax consistency specifically for cross-region reads while keeping it strong within a single region.

    #c-why-strong-consistency-has-an-unavoidable-latency-cost-acros
  5. 05Quorum reads/writes (`W + R > N`) — tuning consistency vs availability

    For a dataset replicated across N nodes, define a write quorum W (writes must be acknowledged by at least W replicas to succeed) and a read quorum R (reads must consult at least R replicas and return the most recent value among them). If W + R > N, any read quorum and any write quorum are guaranteed to overlap in at least one replica, so a read is guaranteed to see the most recent successful write — this is how systems like Cassandra or DynamoDB let you dial consistency per operation rather than committing to one system-wide policy: W = N, R = 1 gives fast reads at the cost of slow, less-available writes (every replica must ack); W = 1, R = N gives fast writes at the cost of slow reads; W = R = (N/2 + 1) (majority quorums) balances both while tolerating some node failures. Choosing W + R <= N deliberately trades this guarantee away for lower latency/higher availability, accepting that a read can occasionally miss the most recent write — a legitimate choice for workloads that can tolerate it.

    #c-quorum-readswrites-w-r-n-tuning-consistency-vs-availability
  6. 06The real cost of "just make everything strongly consistent"

    The reasoning-simplicity argument is genuinely real — eventual consistency introduces real application-level complexity (handling stale reads, conflict resolution, causal-ordering bugs) that strong consistency sidesteps entirely. The cost that argues against defaulting to it everywhere: availability and latency, concretely — every write (and often every read, depending on the design) now depends on reaching a quorum or a single leader, so a partition or a slow node directly becomes user-facing unavailability or latency rather than being absorbed; and it does not scale horizontally for free the way eventually-consistent replication does, since coordination overhead grows with replica count and geographic spread. Push back specifically when: the workload is read-heavy and tolerant of brief staleness (most content-serving systems), the system needs to serve users across regions with low latency, or availability during a partial outage genuinely matters more than every reader seeing the absolute latest write (most consumer-facing products, versus a financial ledger). The right answer is rarely “always strong” or “always eventual” — it is picking consistency per data type, since most real systems have both a small strongly-consistent core (payments, inventory counts, auth) and a much larger eventually-consistent periphery (feeds, counts, recommendations) in the same product.

    #c-the-real-cost-of-just-make-everything-strongly-consistent
  7. 07Read-your-own-writes — a bug from assuming stronger consistency than you have

    A common one: a service writes a record to a primary database, then immediately reads it back from a read replica to confirm and use in the same request — under asynchronous (eventually consistent) replication, that read can miss the write entirely if it lands on the replica before replication lag catches up, producing a spurious “not found” or stale value right after a successful write, even though nothing actually failed. This is the read-your-own-writes consistency violation, and it is a frequent real bug specifically because eventual consistency’s staleness window is often small enough in testing/low-load conditions to go unnoticed, then shows up intermittently in production under real replication lag. Fixes: route the immediate post-write read to the primary rather than a replica for that specific request (session-level read-your-writes guarantee), or design the write path to return the written value directly from the write call itself rather than requiring a separate read at all.

    #c-read-your-own-writes-a-bug-from-assuming-stronger-consistenc