advanced25 min studyLesson 258 in Engineering

Causal consistency: carry the history a session depends on

Use dependency frontiers to connect read-your-writes, monotonic reads, monotonic writes, and writes-follow-reads.

On this page

What you’ll understand

  • Identify causal dependencies created by program order and read observations.
  • Check a server’s coverage against a session’s required frontier.
  • Distinguish session guarantees and causal visibility from global real-time order.

A convergent value can still provide a confusing experience if a person writes an update and immediately reads an older view on another replica. Session guarantees constrain the history a client may observe or build on while it moves between servers. Causal consistency goes further by respecting relevant dependencies across operations. These guarantees require retaining and checking context; a load balancer cannot infer them from the fact that all replicas may eventually converge.

Dependencies come from observations and order

If a client reads a post and then writes a reply based on it, that reply depends on the observed post. Program order also relates operations within the defined session model, and transitivity carries dependencies through multiple clients and messages. A causally consistent visibility rule must not expose an update without the relevant causal prerequisites. Concurrent updates have no such ordering relation and may still need a type-specific resolution rule. Causal order is therefore a partial order, not a universal latest value for every key.

A system needs a stated causality scope: objects, partitions, services, and sessions can have different boundaries. Tracking a token for one object does not automatically capture a dependency on another service’s result. Likewise, a client that drops its causal token on reconnect can lose the basis for its session guarantees. An implementation may route to a sufficiently current replica, wait for dependencies, fetch missing context, or explicitly reject the requested guarantee. It cannot simply return a stale value and call the guarantee satisfied.

a→b∧b→c  ⟹  a→c,deps⁡(u)⊆Hvisiblea\to b\land b\to c\implies a\to c,\qquad \operatorname{deps}(u)\subseteq H_{\rm visible}
The first expression is transitivity of happened-before. The second sketches the prerequisite-history requirement when exposing update u: its dependency set must be covered by the visible history. It does not require exposing every concurrent update.↔ Scroll wide equations horizontally.

Four session guarantees address different surprises

Read-your-writes requires later reads in the session to reflect its prior writes under the object’s semantics. Monotonic reads prevents a session from moving backward to a history that omits updates it already observed. Monotonic writes preserves the session’s write order at downstream observation. Writes-follow-reads preserves dependencies from what a session read to what it subsequently wrote. They are related obligations but should not be collapsed into one casual phrase such as sticky sessions. Merely revisiting one server may fail after that server loses state or forwards work.

For a fixed-actor prefix model, represent the client’s required history by vector c and a server’s applied history by s. Coverage requires s to dominate c componentwise, assuming those counters describe the same scope and complete prefixes. A server with a larger sum can still miss one required actor’s event. More elaborate systems use dependency checks and metadata specific to their partitioning and replication design. The vector example is a concrete coverage test, not a claim that every causal store uses one global vector.

eligible⁡(s,c)  ⟺  ∀i, si≥ci\operatorname{eligible}(s,c)\iff\forall i,\ s_i\geq c_i
s and c are compatible fixed-actor prefix frontiers for the same relevant data scope. Eligibility here means history coverage only; permissions, failure state, cross-object atomicity, and conflict interpretation are separate checks.↔ Scroll wide equations horizontally.

Causal service can trade availability for a promised view

A disconnected replica that lacks a dependency cannot honestly serve a read requiring that dependency until it obtains the missing information or declines the guarantee. This is a practical availability consequence, even if ordinary local writes remain possible. Causal consistency also does not imply linearizability: two unrelated concurrent writes need not be placed in a real-time total order. Define the user-facing behavior under missing context, and measure how often sessions wait or reroute rather than hiding that cost behind average read latency.

The queue lab illustrates waiting for progress, not causal correctness. Reset, set λ=2 and μ=3, predict the initial backlog of four drains at t=4, then Play or Step. Reset and set λ=4, μ=3 to predict persistent growth instead. The fluid backlog has no actor histories, token checks, or dependency visibility rules. Its value is in separating a waiting-capacity question from the discrete coverage check in the worked example. Faster service does not itself prove that the specific missing dependency arrived.

A larger total can still miss a dependency

A session requires frontier c=(3,2). Server S has applied s=(4,1), while server T has applied t=(3,3). Which covers the session requirement?

  1. Compare S componentwise: four covers the required three A events, but one does not cover two B events. S is ineligible despite its extra A progress.

  2. Compare T: three covers three and three covers two, so T is eligible under the frontier-coverage rule. The minimum missing progress at S is one B event, assuming the prefix counter represents that exact history scope.

  3. The sum of required entries is five, and S’s sum is also five. Equal totals did not establish coverage. Route to T, obtain the missing B prefix at S, or explicitly decline the guarantee rather than silently serving an insufficient view.

The result

T covers the session frontier; S does not. Componentwise causal coverage cannot be replaced by a scalar progress score.

Explore the model

Interactive lab

Interactive lab · queue

Waiting capacity is separate from causal coverage

Reset, set λ=2 and μ=3, predict backlog max(0,4−t), then Play or Step. Reset and set both λ=4 and μ=3 for growing backlog. This fluid queue does not track dependency tokens, causal order, or session guarantees.

Waiting capacity is separate from causal coverageFluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Current readings: Fluid backlog: 4; Net rate · λ − μ: −1 /s; M/M/1 mean residence: 1 s. All parameters are adjustable with the labeled controls below.02.557.51001.534.56Elapsed time · sFluid backlogλ < μ
Fluid backlogCurrent time
Fluid backlog
4
Net rate · λ − μ
−1 /s
M/M/1 mean residence
1 s
t = 0 s

Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forA system may wait for missing context, but queue drainage alone does not prove that the required history is present.

Check your understanding

A session reads update A, then creates update B based on it. Which guarantee directly addresses propagating that read dependency into its write?

Try it yourself

A session requires c=(2,4,1). Server s=(3,3,5) has a larger entry sum. Is it eligible under the same prefix model, and what is missing?

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Check every matching component; do not compare sums.

Compare with the solution

It is ineligible because its B component is three while the session requires four. One additional B-prefix event is missing; extra A and C events cannot replace it. This coverage conclusion assumes comparable counters and says nothing by itself about permissions or multi-object atomicity.

Take it with you

  • Causal dependencies follow observations, session order, and transitivity.
  • The four session guarantees address distinct visibility and propagation requirements.
  • Causal coverage is partial-order knowledge, not a global real-time transaction order.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.