<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/read-your-own-writes-off-the-primary-05eoq804o" -->

---
title: Read your own writes, off the primary | daily.dev
description: PostgreSQL 19 introduces the WAIT FOR LSN command, letting a reader block on a replica until a specific WAL position has been replayed, solving the classic...
canonical: https://daily.dev/posts/read-your-own-writes-off-the-primary-05eoq804o
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Read your own writes, off the primary | daily.dev
og:description: PostgreSQL 19 introduces the WAIT FOR LSN command, letting a reader block on a replica until a specific WAL position has been replayed, solving the classic...
og:url: https://daily.dev/posts/read-your-own-writes-off-the-primary-05eoq804o
og:image: https://api.daily.dev/og/posts/05eoQ804O.png
og:image:alt: Read your own writes, off the primary
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Read your own writes, off the primary

**[Planet PostgreSQL](https://daily.dev/sources/planet-postgresql)** · 18 min read · 0 upvotes · 0 comments

## Summary

PostgreSQL 19 introduces the WAIT FOR LSN command, letting a reader block on a replica until a specific WAL position has been replayed, solving the classic read-your-own-writes problem when reads are routed off the primary. Benchmarks show naive replica reads return stale data 99% of the time in a low-latency loopback setup, while sleep-based delays add 50ms+ of latency and synchronous_commit=on doesn't guarantee replay (only flush). WAIT FOR adds only 1-2ms over reading the primary directly. The piece covers MODE and TIMEOUT semantics, connection pool implications, correct LSN capture (post-commit, not mid-transaction), a Go sample implementation, and framework-specific gotchas including Rails/Active Record treating WAIT FOR as a write by default and PgBouncer transaction-mode behavior.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://postgr.es/p/9tB>

## Questions this post answers

### What does WAIT FOR LSN do in PostgreSQL 19?

WAIT FOR LSN is a new top-level SQL command in PostgreSQL 19 that runs on a standby and blocks until it has replayed a specified WAL position, then returns. It supports a MODE option (standby_replay is the default and only mode that guarantees visibility to queries), a TIMEOUT, and NO_THROW, which converts errors into a status row instead of raising.

_Track PostgreSQL 19 features like this on daily.dev before they show up as production surprises._

### Why does synchronous_commit = on still allow stale reads on a PostgreSQL replica?

Because synchronous_commit=on waits for the standby to flush the WAL to disk, not to replay it, and a read can land in the gap between those two instants. In testing, this configuration still produced stale reads on roughly 3 to 17 out of 600 attempts. Only remote_apply, which waits for actual replay, closes that gap, but it does so for every writer, not just the reader that needs it.

_Compare synchronous_commit settings against WAIT FOR on daily.dev before picking a replica consistency strategy._

### How do I capture the correct LSN in PostgreSQL to check replica replay status after a write?

Call pg_current_wal_flush_lsn() on the primary after the commit completes, not pg_current_wal_insert_lsn() inside the transaction. The in-transaction position can be about 40 bytes short of the actual commit record, so a replica that replays up to that earlier LSN has applied the row's INSERT but not yet the COMMIT that makes it visible to queries.

_Developers wiring up replica read consistency check patterns like this against daily.dev before shipping._

---

Tags: [#backend](https://daily.dev/tags/backend), [#golang](https://daily.dev/tags/golang), [#postgresql](https://daily.dev/tags/postgresql)

[View this post on daily.dev](https://daily.dev/posts/read-your-own-writes-off-the-primary-05eoq804o)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Read your own writes, off the primary","url":"https://daily.dev/posts/read-your-own-writes-off-the-primary-05eoq804o","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/read-your-own-writes-off-the-primary-05eoq804o"},"datePublished":"2026-08-31T23:01:00.481Z","dateModified":"2026-09-06T21:29:37.497Z","description":"PostgreSQL 19 introduces the WAIT FOR LSN command, letting a reader block on a replica until a specific WAL position has been replayed, solving the classic...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/b8c4e46bbcdb81b39671abac7b700f7a?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/b8c4e46bbcdb81b39671abac7b700f7a?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Planet PostgreSQL","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Planet PostgreSQL","logo":"https://media.daily.dev/image/upload/logos/placeholder.jpg","url":"https://daily.dev/sources/planet-postgresql"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/read-your-own-writes-off-the-primary-05eoq804o","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"backend,golang,postgresql","timeRequired":"PT18M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Planet PostgreSQL","item":"https://daily.dev/sources/planet-postgresql"},{"@type":"ListItem","position":3,"name":"Read your own writes, off the primary"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/read-your-own-writes-off-the-primary-05eoq804o#faq","mainEntity":[{"@type":"Question","name":"What does WAIT FOR LSN do in PostgreSQL 19?","acceptedAnswer":{"@type":"Answer","text":"WAIT FOR LSN is a new top-level SQL command in PostgreSQL 19 that runs on a standby and blocks until it has replayed a specified WAL position, then returns. It supports a MODE option (standby_replay is the default and only mode that guarantees visibility to queries), a TIMEOUT, and NO_THROW, which converts errors into a status row instead of raising. Track PostgreSQL 19 features like this on daily.dev before they show up as production surprises."}},{"@type":"Question","name":"Why does synchronous_commit = on still allow stale reads on a PostgreSQL replica?","acceptedAnswer":{"@type":"Answer","text":"Because synchronous_commit=on waits for the standby to flush the WAL to disk, not to replay it, and a read can land in the gap between those two instants. In testing, this configuration still produced stale reads on roughly 3 to 17 out of 600 attempts. Only remote_apply, which waits for actual replay, closes that gap, but it does so for every writer, not just the reader that needs it. Compare synchronous_commit settings against WAIT FOR on daily.dev before picking a replica consistency strategy."}},{"@type":"Question","name":"How do I capture the correct LSN in PostgreSQL to check replica replay status after a write?","acceptedAnswer":{"@type":"Answer","text":"Call pg_current_wal_flush_lsn() on the primary after the commit completes, not pg_current_wal_insert_lsn() inside the transaction. The in-transaction position can be about 40 bytes short of the actual commit record, so a replica that replays up to that earlier LSN has applied the row's INSERT but not yet the COMMIT that makes it visible to queries. Developers wiring up replica read consistency check patterns like this against daily.dev before shipping."}}]}
```

