The replica has not received the write yet. This delay is called replication lag.
PostgreSQL streaming replication is asynchronous by default. The primary commits the change and returns success first. Then it sends the WAL (Write-Ahead Log: the record of every change) to the replicas, and they apply it a moment later. The lag is usually milliseconds, but it can be seconds or more under heavy load. If a read goes to a replica that is behind, it returns the old row.
Ways to get read-your-writes (a user always sees their own changes):
- Send a user's reads to the primary right after that user writes. For example, do it for a few seconds after the write, or for the rest of the request.
- Save the WAL position of the write with
pg_current_wal_lsn(). Read from a replica only after it has replayed past that point. Check this withpg_last_wal_replay_lsn()on the replica. - Use synchronous replication with
remote_apply. This also works, but it makes every commit slower.
Watch the lag with pg_stat_replication on the primary. Keep reads that must be fully up to date on the primary, for example a balance check before a payment.
- Asynchronous replication causes lag, so a replica can return old data.
- Send a user's reads to the primary right after that user writes.
- Compare WAL positions (LSN) before reading from a replica.
- Synchronous replication with remote_apply gives consistency but slows every commit.
- Monitor replication lag with pg_stat_replication.