CONCEPT Cited by 1 source
Read-your-writes consistency¶
Definition¶
Read-your-writes consistency (RYW) is the session-consistency guarantee that, within a single client session, any read issued after a successful write observes a state that includes that write (or a later one). It is a strictly weaker property than strong consistency — other sessions may still see stale state — but strictly stronger than raw eventual consistency, which permits a session to fail to see its own writes.
Formally, for a session S with writes w1, w2, … committed at
times t_w1, t_w2, … and a read r issued at time t_r:
The guarantee is scoped to session S: a different session may
observe a pre-w_i state at the same wall-clock time and that does
not violate RYW.
Why it matters¶
RYW is the consistency floor a human user "feels". A user clicks "Save", the request succeeds, the page reloads — and the user's own edit is gone. This is the single most common way users perceive a database as "broken", even if the system is technically eventually consistent and the edit will show up in ~100 ms. It is the UX contract of basically every interactive application:
"This tells Rails to send all reads to our read-only region and writes to our primary. After each write, it will set a cookie that will send all reads to the primary for 2 seconds, allowing users to read their own writes." (Source: sources/2026-04-21-planetscale-introducing-planetscale-portals-read-only-regions.)
The PlanetScale Portals launch post is canonical because it names the problem explicitly ("This protects our users from ever reading stale data due to replication lag") and provides the canonical mechanism — a session cookie pinning reads to primary for a bounded window.
How RYW breaks¶
RYW is trivially preserved in a single-primary / read-from-primary architecture: every read goes to the same server that committed the write, so the write is visible by construction.
RYW breaks the moment a system introduces
read-write splitting — writes to primary, reads to replica pool.
A write commits on primary at time t_w. The write propagates to
replica R at time t_w + lag(R). A read issued to R in the
window [t_w, t_w + lag(R)) returns pre-write state. This window
is replication-lag-sized — typically
sub-second on a healthy cluster, but unbounded during replication
stalls.
RYW breaks harder with regional read replicas: cross-region lag is larger (cross-ocean is ~100 ms minimum just from physics, often 500 ms–several seconds under load), and the blast radius of a stalled replica is an entire region's read traffic returning ghost-reads.
Four mechanisms to preserve RYW¶
1. Read from primary always. Trivially correct; throws away the entire point of having replicas. Used for write-your-writes-critical flows by exception (e.g. a form submission's post-save redirect).
2. Sticky session → sticky replica, plus lag < sticky-window.
Pin a user's reads to a specific replica. If the replica is caught
up at time t_w (synchronously replicated primary → replica), RYW
holds. Brittle — requires a session-layer routing primitive and a
tight bound on replica lag.
3. Session token / LSN / GTID comparison. Server returns an
opaque position token on write; the client includes the token on
subsequent reads; a read that cannot be satisfied at that token is
either delayed or forwarded to primary. Correct, precise, but
requires token plumbing through every request path.
Approximates what MongoDB's $clusterTime
and PostgreSQL's logical sequence numbers offer natively.
4. Time-bounded primary-read window after write. On commit, set
a flag (cookie, session variable, in-memory TTL) that forces the
user's subsequent reads to primary for Δ seconds. Correct iff
Δ > max(lag(R)) over the replica pool — the classic
session-cookie
pattern from the Portals post. Cheap, coarse, works with any ORM
that supports role switching (Rails DatabaseSelector, Django
router, Laravel DB::connection('read'), etc.).
Failure modes¶
- Δ too small for p99 replication lag. User occasionally sees ghost-reads. Debugging signal: users complain "my edit disappeared and then came back 3 s later". The 2 s default in the Portals post is reasonable for a healthy cluster but insufficient during replication stalls.
- Cookie not set / not propagated. Some auth flows, agent traffic, or server-to-server calls may not carry the session cookie, so they always read from replica regardless of recent-write status. Typically fine for agents (they don't care about RYW for their own writes) but a source of subtle bugs.
- Write failure + optimistic cookie. If the app sets the cookie before knowing whether the write committed, a write that rolled back still pins the user to primary for Δ seconds. Harmless in that direction — the user reads fresher data than necessary, not staler.
RYW vs. related models¶
| Model | Within session | Across sessions |
|---|---|---|
| Strong consistency | ✓ | ✓ |
| Monotonic reads | reads never go backwards in time | ✗ |
| Read-your-writes | ✓ (your own writes) | ✗ |
| Monotonic writes | own writes applied in order | n/a |
| Eventual consistency | ✗ | ✗ |
RYW is one of four session guarantees (Terry et al., 1994); any RYW-enforcing mechanism also typically gives monotonic reads as a side effect if it uses a monotonic position token (#3 above) or pins to a single replica (#2 above).
Seen in¶
- sources/2026-04-21-planetscale-introducing-planetscale-portals-read-only-regions — names the mechanism (session cookie + 2 s primary-read window) as the canonical in-ORM RYW preservation pattern.
Related¶
- concepts/replication-lag — the staleness distribution RYW mechanisms have to cover.
- concepts/read-write-splitting — the architectural choice that creates the RYW problem in the first place.
- concepts/session-cookie-read-your-writes-window — mechanism- focused sibling concept.
- concepts/regional-read-replica — amplifies RYW stakes by enlarging the lag distribution.
- concepts/strong-consistency — the stronger model RYW trades off against.
- concepts/consistent-read — related read-side primitive.
- patterns/session-cookie-for-read-your-writes — the pattern page.
- patterns/per-region-read-replica-routing — the other half of the pair (routing to the replica; this concept covers routing away from the replica for a bounded window).
- systems/planetscale-portals — canonical productised instance.