---
title: "Read your writes: WAIT FOR in PostgreSQL 19"
description: "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."
---

# Read your writes: WAIT FOR in PostgreSQL 19

[Clickhouse](https://yomu.fyi/company/clickhouse) · Aug 25, 2026

**Type:** Explainer

## 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.

**Tags:** [Monitoring](https://yomu.fyi/topic/monitoring), [Performance](https://yomu.fyi/topic/performance), [Postgres](https://yomu.fyi/topic/postgres), [Reliability](https://yomu.fyi/topic/reliability)

- Source: [Clickhouse](https://clickhouse.com/blog/postgresql-19-wait-for-read-your-writes)
- Source URL: https://clickhouse.com/blog/postgresql-19-wait-for-read-your-writes
- Ingested by Yomu: 2026-08-29T07:47:10.688Z

[Read original post](https://clickhouse.com/blog/postgresql-19-wait-for-read-your-writes)
