Read-After-Write Consistency and Replica Lag

A successful database write can still be invisible on a read replica, which is why an API can return 200 𝘖𝘒 for a newly created record while the very next screen insists that the same record does not exist.
How Replica Lag Affects Reads
In a PostgreSQL deployment with asynchronous replication, the primary commits a transaction and acknowledges the write before a read replica has necessarily replayed the WAL records that make the change visible.
The timing explains the contradiction: at t0 the primary commits version 8, at t1 a GET reaches a replica still showing version 7, and only at t2 does WAL replay advance far enough for the new state to appear.
That distinction matters in workflows that assume read-after-write consistency, such as updating a profile and immediately opening its detail page, where stale data looks like a failed save even though the commit succeeded.
Ensuring Visibility After a Write
One practical option is to route the read following a mutation to the primary, or temporarily keep that user on primary reads, trading some read-scaling capacity for more predictable visibility.
If reads must use a replica, the application can coordinate around a post-commit WAL position and wait for the chosen replica to replay through it, with a bounded deadline and an explicit fallback when it falls behind.
Monitoring Lag and Defining the Contract
Monitor replication lag, but do not confuse a healthy average lag metric with a guarantee for an individual request. Commit acknowledgement, synchronous replication configuration, and replica query visibility are distinct concerns.
The important contract is not simply whether a write succeeded, but whether the next read is allowed to return an older state. Once that expectation is explicit, routing and replication become deliberate architectural choices.
AI Disclosure: The ideas and content are my own. I use LLMs to improve clarity and polish my writing.