Read Repair on Access¶
Read-path repair method — instantiates Asynchronous Replica Convergence
Fixes divergence lazily on the read path: when a read finds replicas disagreeing, it returns the freshest value and quietly writes it back to the stale ones.
Read Repair on Access turns every read into an opportunity to heal. When a read consults more than one replica and finds them disagreeing, it resolves to the freshest value, serves that to the caller, and — as a background side effect — writes it back to the replicas that were behind. Its defining move is that repair rides the read path and touches only data that is actually accessed: hot, frequently-read keys converge continuously and for almost free, while nothing is spent on data no one is looking at. It is the lazy, opportunistic counterpart to a scheduled sweep — repair as a by-product of serving traffic.
Example¶
A feature-flag service is read constantly by every app instance and replicated for low latency. A flag, checkout_v2, was flipped on, but during a brief partition the write reached only two of the three replicas. An app instance reads the flag from the two nearest replicas: one returns the new on, the other the stale off. Read repair compares their versions, sees on is newer, returns on to the caller — so the reader is never served the stale value — and then asynchronously writes on back to the lagging replica.
The very next reader near that replica now sees the corrected flag. A cold, rarely-read flag sitting on the same stale replica stays unrepaired until the background sweep reaches it, which is harmless because nothing is reading it. The read both got the right answer and left the system a little more converged than it found it.
How it works¶
What distinguishes it from the other repair mechanisms is that it is pulled by reads, not pushed on a schedule. On a read it fans out to two or more replicas (or a read quorum), compares their versions to spot a mismatch beyond a staleness bound, picks the freshest, and returns it — guaranteeing the caller sees a consistent value even before the system is fully repaired. The corrective write-back to stale replicas is issued off the critical path, so healing does not slow the read. It repairs exactly the keys traffic touches and no others, which is its whole efficiency and its whole limitation.
Tuning parameters¶
- Read breadth — how many replicas each read consults. More replicas catch more disagreement and repair more aggressively, but add read latency and load; reading just one repairs nothing.
- Staleness threshold — how far behind a replica's value must be before a read treats it as needing repair. Tight thresholds heal eagerly and cost more write-backs; loose ones tolerate small lag.
- Write-back timing — asynchronous (fast reads, the replica converges a beat later) versus synchronous (the read blocks until laggards are fixed, giving stronger read-your-writes at the cost of latency).
- Repair sampling — repair on every qualifying read, or only a sampled fraction, to cap write amplification on very hot keys.
When it helps, and when it misleads¶
Its strength is self-healing consistency for the data that matters most — whatever is actually being read — with no separate job to run, and it guards each individual read from returning a stale answer even mid-convergence, which is what makes reads feel monotonic.[1] Its honest limit is the flip side of that efficiency: it only heals what is read, so cold, rarely-accessed keys can stay divergent indefinitely — read repair is not a substitute for a background sweep. It also adds read-time work and extra write traffic, and a read that consults only one replica does no repair at all. The classic misuse is leaning on read repair alone for convergence, quietly letting unread data rot, or making every write-back synchronous and paying quorum latency on every read. The discipline is to pair it with an exhaustive background exchange for cold data and to keep the corrective write off the read's critical path.
How it implements the components¶
Read Repair on Access fills the read-path guard components — the ones a repair that rides reads can fill:
staleness_threshold— the read-time trigger: how out-of-date a replica's value must be before the read treats it as stale and repairs it.state_consistency_guard— by resolving to the freshest value and correcting laggards, it guards each read against returning stale or inconsistent state.side_effect_boundary— the repair is a bounded side effect of the read: an asynchronous write-back kept off the critical path so healing never degrades the read.
It does not sweep cold, un-read data (that is Anti-Entropy Reconciliation Exchange) or define how two genuinely concurrent values combine (CRDT-Like State Merge, using the ordering from Version-Vector or Dotted-Context Exchange). It heals only what a read touches.
Related¶
- Instantiates: Asynchronous Replica Convergence — it converges the hot, actually-read subset of the data as a by-product of serving reads.
- Consumes: Version-Vector or Dotted-Context Exchange to tell which of the returned values is freshest.
- Sibling mechanisms: Anti-Entropy Reconciliation Exchange · Hinted-Handoff Buffer · Merkle-Tree Divergence Scan · Replicated Record Store · CRDT-Like State Merge
References¶
[1] Monotonic-read consistency — the guarantee that a client, having seen a value, never later sees an older one. By resolving to and propagating the freshest value at read time, read repair helps a replicated store approximate this on the paths that are actually read, even while other replicas are still catching up. ↩