Read-Model Version Gate¶
Read-time protocol — instantiates Access-Optimized Redundant Representation
Attaches a required version or freshness precondition to a read, and blocks, waits, or falls back when the redundant copy has not yet caught up to it — so a reader never sees a copy older than the write it just made.
A Read-Model Version Gate is a protocol that sits in front of a redundant read copy and enforces a precondition on every guarded read: the copy must have advanced to at least a required version before it is allowed to answer. The reader (or its session) carries a token — the version or position it must not read behind — and the gate compares that token against the copy's current watermark. If the copy is caught up, the read passes through untouched; if it is behind, the gate does not silently serve stale data — it waits briefly, routes to the source, or returns an explicit degraded response. Its defining move is converting eventual consistency's "you might see old data" into a contract: this read will not observe a version older than the one you require, or it will tell you it cannot.
Example¶
A collaboration app serves user settings from a fast read replica. A user changes their display name and lands back on their profile — which reads from the replica. Replication lag is usually milliseconds, but occasionally seconds, and in that window the profile would show the old name: the user just made a change and the app appears to have lost it. The classic eventual-consistency papercut.
The team gates the read. On save, the write returns the source position of the commit, and the session carries it as a required-version token. The profile read is now guarded: the gate checks the replica's freshness watermark against the token. Caught up — serve from the replica as normal. Behind — for up to 500 ms the gate waits for the watermark to pass; if it still has not, it falls back to reading that one record from the source so the user reliably sees their own change. Other users, who carry no such token, keep reading the fast replica happily. The gate spends the expensive fallback only where the guarantee is actually needed.
How it works¶
- Carry a required version. A write hands back the source position it committed at; the reader or session keeps it as the floor the copy must reach before a guarded read is valid.
- Check the copy against the floor. At read time the gate compares the required token to the copy's published watermark — a fast, local comparison, not a source round-trip.
- Choose a path when behind. If the copy has not reached the required version, apply the configured fallback: bounded wait, read-through to source, or an explicit degraded response — never a silent stale read.
Tuning parameters¶
- Wait budget — how long the gate blocks for the copy to catch up before falling back. Longer waits raise the hit rate on the fast copy but add tail latency; zero-wait fails over immediately at more source load.
- Fallback path — wait, read-through to source, or serve-degraded-with-notice. Read-through preserves correctness at source cost; degraded serving preserves availability by admitting to the reader that the answer may be stale.
- Gate scope — which reads are gated. Gating everything is safe but forfeits the copy's benefit; gating only reads that follow the reader's own writes (read-your-writes) spends the cost precisely where the guarantee matters.
- Token granularity — a global position versus a per-entity version. Global is simple but over-blocks; per-entity waits only on the specific record the reader needs current.
When it helps, and when it misleads¶
Its strength is giving a redundant copy a bounded, per-read consistency guarantee without abandoning it — most reads still hit the fast copy, and only those that genuinely require currency pay for it. It is the standard way to deliver read-your-writes or monotonic-read guarantees[1] on top of an eventually-consistent read model, and it degrades honestly instead of lying when the copy is behind.
It misleads when it is asked to compensate for a chronically lagging copy: if the watermark is usually behind the required version, the gate falls through to source constantly and the read model stops relieving load — the gate is treating a synchronization problem as a read problem. Over-gating is the mirror failure: guard every read and you have re-serialized everything against the source, forfeiting the whole point of the copy. And a gate is only as trustworthy as the watermark it checks — an optimistic watermark makes the gate confidently wrong. The discipline is to gate narrowly (typically only reads behind a reader's own recent write), keep the fallback bounded and explicit, and fix persistent lag at the refresh layer rather than papering over it at the gate.
How it implements the components¶
Read-Model Version Gate supplies the read-time enforcement components — the contract and its fallback, not the copy or its freshness measurement:
read_path_contract— it is the contract the read path offers: a guarded read will not observe a version older than the caller's required token, or it will fail over explicitly.version_token— it defines and checks the required-version token a reader carries, comparing it to the copy's position at every guarded read.degraded_read_mode— when the copy is behind, it selects the fallback behaviour (wait, read-through, or serve-degraded) rather than serving a silent stale answer.
It does not measure or publish the copy's current position (freshness_and_staleness_bound, divergence_signal) — it consumes that from Freshness Watermark — and it neither stores nor refreshes the copy, which are the artifact and refresh siblings.
Related¶
- Instantiates: Access-Optimized Redundant Representation — the gate makes a redundant copy safe to read behind a per-read consistency contract.
- Consumes: Freshness Watermark — the gate checks the required version against the watermark's published position.
- Sibling mechanisms: Freshness Watermark · Scheduled Incremental Refresh · CQRS Read-Model Projection · Event-Sourced Projection · Materialized View
References¶
[1] Read-your-writes and monotonic reads are named session-consistency guarantees: a reader always sees its own prior writes, and never sees data move backward in time. A version gate is the standard way to provide them over an eventually-consistent copy — by holding the read to a required version rather than strengthening the whole store. ↩