Consistency Models
Purpose
Specify the weakest set of guarantees that satisfies observable requirements and price it. The
models are not one total ladder: recency, ordering, session, convergence and multi-object atomicity
are different dimensions. Stronger coordination often costs latency or partition availability,
but the cost depends on topology, implementation and workload.
The failure this prevents is the requirement expressed as a model name. "We need strong
consistency" cannot be verified, priced, or tested. "A user must never see their own
comment disappear after posting it because a replica has not applied the write" names an
observation. Eventual convergence alone is insufficient; it can coexist with read-your-writes
for that session. No global linearizability requirement follows from this observation alone.
Workflow
- State the requirement as something a client observes. "Two users must never both be
assigned seat 14C." "A user must never see their own write disappear." "A balance may lag
by up to five seconds but must never go backwards." No model names yet.
- Ask who observes it. Requirements that hold only for the session that performed the
write may need session guarantees. Compare their routing and metadata costs with the
coordination required by the actual cross-client contract.
- Map each requirement to guarantees and scope, using
references/requirement-to-model.md: object/key range, session versus all clients, normal
operation versus partition, and any time bound. Record the cost and fallback.
- Trace the whole read path, not the database. A linearizable store behind a
read-replica router, a CDN, or a cache delivers the weakest link in the chain. The path
has a consistency model; the store only has one of its components.
- Separate but connect isolation from consistency explicitly. Decide the transaction isolation
level for interactions among concurrent transactions, and the distributed model for ordering
and recency across nodes; a product may bundle these as strict serializability.
- Write a test that fails under the model you rejected. Stale-read detection with a
deliberately lagged replica, or a partition injected with a network fault. Techniques are
in
references/read-your-writes-in-java.md.
Inspect the project's JDK, resolved Spring/driver versions, transaction manager, replication mode,
commit acknowledgement policy and read routing before proposing implementation details. The Java
reference contains partial Spring sketches, not a declared runnable Java baseline. When evidence
is absent, state the candidate guarantee and the missing configuration or experiment; do not infer
semantics from annotations or topology names. Deliver the observable contract, affected path,
supporting evidence, failure behavior and one test that distinguishes it from a rejected design.
Rules
- Do not stop at a model name. Name the observation, scope, failure condition and time bound, then map
it. A model name in a requirements document is an unpriced, untestable assertion.
- CAP is about behaviour during a partition, not a general "pick two". With no
partition, the theorem does not force a choice between consistency and availability; it says that
while a partition is in progress, a system cannot both stay linearizable and satisfy CAP's
availability definition for every request to a non-failing node. That theorem-level availability
is not an SLO percentage, and real systems may reject only affected keys/operations.
- PACELC is a useful design heuristic, not a replacement theorem. If Partitioned, choose
Availability or Consistency; Else, choose Latency or Consistency. The else-branch concerns
operation without a partition, including choices such as replica
routing, quorum sizes, cache TTLs.
- Linearizability gives each operation an instantaneous point between invocation and response and
respects real-time precedence. It is compositional across independently linearizable objects,
but two separate operations still do not become one atomic multi-key transaction. Cross-object
invariants need an invariant-preserving protocol. Compensation is an option only when the
business contract permits temporary violations and subsequent repair.
- Serializable isolation is not a recency guarantee. Serializability says the outcome
equals some serial order of transactions; linearizability constrains that order to
respect real time. A serializable transaction may legally read a stale snapshot. Strict
serializability is the conjunction. Isolation level and distributed consistency are
orthogonal axes; naming one does not constrain the other.
- Read-your-writes, monotonic reads, monotonic writes and writes-follow-reads are session
guarantees—often cheaper than global ordering, but session identity, failover, roaming clients,
expiry and watermark storage are part of their cost.
- Causal consistency orders causally related operations and permits different orders for
concurrent ones. Highly available causal designs exist under specific replication/conflict
assumptions; do not convert that into a universal “strongest AP model” claim.
- Eventual consistency promises convergence only under its stated conditions, typically after
updates stop and communication/reconciliation resumes. It has no deadline. A numeric requirement
is bounded staleness/SLA evidence, not plain eventual consistency; measure end-to-end visibility,
not just transport lag.
- A cache in front of a strongly consistent store downgrades the path to the cache's own
staleness behavior. If the requirement is read-your-writes, use a commit/version token or route
to an authoritative path known to include the write; invalidation alone has stale-fill races.
Cache mechanics are
caching-strategies and cache-sharding-and-replication.
@Transactional(readOnly = true) is transaction metadata that frameworks/drivers may use for
routing or optimization; effects vary by stack. By itself it chooses no replica and promises no recency.
- This is not the Java Memory Model.
happens-before, volatile and synchronized
concern visibility between threads sharing one memory; that subject is
java-memory-model. The vocabulary overlaps ("sequential consistency" exists in both) and
the scales do not. Do not reason about replica lag with JMM rules, or the reverse.
Primary sources
References
- Requirement to model — a decision table from an
observable business requirement to sufficient guarantees, with costs and
counterexamples when a needed guarantee is absent. Read when a requirement is being written, or when
a chosen model needs justifying.
- Read-your-writes in Java and Spring — routing a
session's reads to the primary for a bounded window after a write, why
@Transactional(readOnly = true) is not a guarantee, the LazyConnectionDataSourceProxy
trap in routing data sources, and how to detect stale reads in tests. Read when reads are
being sent to replicas.
1---2name: consistency-models3description: Choosing distributed consistency guarantees as an engineering decision: linearizability, sequential/causal ordering, session guarantees (read-your-writes, monotonic reads), bounded staleness and eventual convergence, stated as observable contracts rather than a false total ladder; CAP stated correctly—the choice between C and A exists only while partitioned—and PACELC, replica paths and transaction isolation boundaries. Use when a user cannot see their own write, when a read after a write returns the previous value, when a design names a model instead of an observable requirement, when reads are being routed to replicas, or when someone cites "pick two". Does not cover multi-service atomicity (distributed-transactions-and-sagas), quorum arithmetic (consensus-and-quorums), caches (caching-strategies), replicated cache topology (cache-sharding-and-replication), or the JMM's happens-before (java-memory-model).4---56# Consistency Models78## Purpose910Specify the weakest set of guarantees that satisfies observable requirements and price it. The11models are not one total ladder: recency, ordering, session, convergence and multi-object atomicity12are different dimensions. Stronger coordination often costs latency or partition availability,13but the cost depends on topology, implementation and workload.1415The failure this prevents is the requirement expressed as a model name. "We need strong16consistency" cannot be verified, priced, or tested. "A user must never see their own17comment disappear after posting it because a replica has not applied the write" names an18observation. Eventual convergence alone is insufficient; it can coexist with read-your-writes19for that session. No global linearizability requirement follows from this observation alone.2021## Workflow22231. **State the requirement as something a client observes.** "Two users must never both be24 assigned seat 14C." "A user must never see their own write disappear." "A balance may lag25 by up to five seconds but must never go backwards." No model names yet.262. **Ask who observes it.** Requirements that hold only for the session that performed the27 write may need session guarantees. Compare their routing and metadata costs with the28 coordination required by the actual cross-client contract.293. **Map each requirement to guarantees and scope**, using30 `references/requirement-to-model.md`: object/key range, session versus all clients, normal31 operation versus partition, and any time bound. Record the cost and fallback.324. **Trace the whole read path, not the database.** A linearizable store behind a33 read-replica router, a CDN, or a cache delivers the weakest link in the chain. The path34 has a consistency model; the store only has one of its components.355. **Separate but connect isolation from consistency explicitly.** Decide the transaction isolation36 level for interactions among concurrent transactions, and the distributed model for ordering37 and recency across nodes; a product may bundle these as strict serializability.386. **Write a test that fails under the model you rejected.** Stale-read detection with a39 deliberately lagged replica, or a partition injected with a network fault. Techniques are40 in `references/read-your-writes-in-java.md`.4142Inspect the project's JDK, resolved Spring/driver versions, transaction manager, replication mode,43commit acknowledgement policy and read routing before proposing implementation details. The Java44reference contains partial Spring sketches, not a declared runnable Java baseline. When evidence45is absent, state the candidate guarantee and the missing configuration or experiment; do not infer46semantics from annotations or topology names. Deliver the observable contract, affected path,47supporting evidence, failure behavior and one test that distinguishes it from a rejected design.4849## Rules5051- Do not stop at a model name. Name the observation, scope, failure condition and time bound, then map52 it. A model name in a requirements document is an unpriced, untestable assertion.53- **CAP is about behaviour during a partition, not a general "pick two".** With no54 partition, the theorem does not force a choice between consistency and availability; it says that55 while a partition is in progress, a system cannot both stay linearizable and satisfy CAP's56 availability definition for every request to a non-failing node. That theorem-level availability57 is not an SLO percentage, and real systems may reject only affected keys/operations.58- **PACELC is a useful design heuristic, not a replacement theorem.** If Partitioned, choose59 Availability or Consistency; Else, choose Latency or Consistency. The else-branch concerns60 operation without a partition, including choices such as replica61 routing, quorum sizes, cache TTLs.62- Linearizability gives each operation an instantaneous point between invocation and response and63 respects real-time precedence. It is compositional across independently linearizable objects,64 but two separate operations still do not become one atomic multi-key transaction. Cross-object65 invariants need an invariant-preserving protocol. Compensation is an option only when the66 business contract permits temporary violations and subsequent repair.67- **Serializable isolation is not a recency guarantee.** Serializability says the outcome68 equals _some_ serial order of transactions; linearizability constrains that order to69 respect real time. A serializable transaction may legally read a stale snapshot. Strict70 serializability is the conjunction. Isolation level and distributed consistency are71 orthogonal axes; naming one does not constrain the other.72- Read-your-writes, monotonic reads, monotonic writes and writes-follow-reads are **session73 guarantees**—often cheaper than global ordering, but session identity, failover, roaming clients,74 expiry and watermark storage are part of their cost.75- Causal consistency orders causally related operations and permits different orders for76 concurrent ones. Highly available causal designs exist under specific replication/conflict77 assumptions; do not convert that into a universal “strongest AP model” claim.78- **Eventual consistency promises convergence only under its stated conditions**, typically after79 updates stop and communication/reconciliation resumes. It has no deadline. A numeric requirement80 is bounded staleness/SLA evidence, not plain eventual consistency; measure end-to-end visibility,81 not just transport lag.82- A cache in front of a strongly consistent store downgrades the path to the cache's own83 staleness behavior. If the requirement is read-your-writes, use a commit/version token or route84 to an authoritative path known to include the write; invalidation alone has stale-fill races.85 Cache mechanics are86 `caching-strategies` and `cache-sharding-and-replication`.87- `@Transactional(readOnly = true)` is transaction metadata that frameworks/drivers may use for88 routing or optimization; effects vary by stack. By itself it chooses no replica and promises no recency.89- **This is not the Java Memory Model.** `happens-before`, `volatile` and `synchronized`90 concern visibility between threads sharing one memory; that subject is91 `java-memory-model`. The vocabulary overlaps ("sequential consistency" exists in both) and92 the scales do not. Do not reason about replica lag with JMM rules, or the reverse.9394## Primary sources9596- [Herlihy and Wing — Linearizability](https://cs.brown.edu/~mph/HerlihyW90/p463-herlihy.pdf)97- [Brewer — CAP twelve years later](https://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed/)98- [Terry et al. — Session Guarantees](https://www.cs.cornell.edu/courses/cs734/2000FA/cached%20papers/SessionGuaranteesPDIS_1.html)99- [etcd API guarantees](https://etcd.io/docs/v3.6/learning/api_guarantees/)100101## References102103- [Requirement to model](references/requirement-to-model.md) — a decision table from an104 observable business requirement to sufficient guarantees, with costs and105 counterexamples when a needed guarantee is absent. Read when a requirement is being written, or when106 a chosen model needs justifying.107- [Read-your-writes in Java and Spring](references/read-your-writes-in-java.md) — routing a108 session's reads to the primary for a bounded window after a write, why109 `@Transactional(readOnly = true)` is not a guarantee, the `LazyConnectionDataSourceProxy`110 trap in routing data sources, and how to detect stale reads in tests. Read when reads are111 being sent to replicas.