ClickhouseExplainer
Read your writes: WAIT FOR in PostgreSQL 19
Summary
PostgreSQL 19 introduces the top-level SQL command WAIT FOR, addressing stale reads that can occur when an application writes to a primary and immediately reads from an asynchronously replicated standby. After the write, the client or pooler obtains an LSN with pg_current_wal_insert_lsn() and sends it to the reading session, where WAIT FOR blocks until the requested WAL position reaches the selected stage. The default standby_replay mode makes the change visible, while standby_write, standby_flush, primary_flush, TIMEOUT, and NO_THROW provide other durability and error-handling choices. The command waits without holding a snapshot, avoiding a replay self-deadlock, and exposes related wait events in pg_stat_activity. The feature preserves asynchronous writes by making only reads that require read-your-writes consistency wait, though timeline changes after promotion require caution.
Context
Asynchronous streaming replication can leave a standby briefly behind the primary, so a read immediately following a write may return stale data or no row. Existing choices included making every commit wait for remote replay, implementing application-side polling, or reading from the primary instead of using replicas.
Approach / What changed
After a write, the client or connection pooler records a WAL position, typically from pg_current_wal_insert_lsn(), and passes it to the session that will read from the standby. That session runs WAIT FOR LSN, optionally selecting a WAL progress mode and timeout, before issuing the read. WAIT FOR runs as a top-level, snapshot-free utility command so replay is not blocked by the waiting session's snapshot.
Takeaways
The default standby_replay mode waits until WAL has been replayed and the changes are visible on the standby; standby_write and standby_flush wait for earlier or stronger progress stages, while primary_flush targets the primary.
TIMEOUT causes an error by default when the wait expires; adding NO_THROW returns success, timeout, or not in recovery instead. An omitted or zero timeout waits indefinitely.
WAIT FOR compares LSN positions without understanding timelines, so a promotion can make a successful result refer to WAL from a different timeline than the original write.
Source and freshness
- Source
- clickhouse.com
- Published
- Added to Yomu
- Last updated
Summaries are generated from the original by a language model. Check the original before relying on it.
Keep reading
Related reading
The Good Stuff
Paid picks we use ourselves. Links carry a referral code — a subscription through one earns us a commission at no extra cost to you.
The best engineering reads, once a week
One useful email. Unsubscribe anytime.