Synchronous vs Asynchronous
Async replication favors throughput and low commit latency; sync replication narrows RPO at the cost of standby latency and availability sensitivity.
Search across all documentation pages
Async replication favors throughput and low commit latency; sync replication narrows RPO at the cost of standby latency and availability sensitivity.
Default async on primary; add one sync standby for tier-0 data.
-- Async (default): commits return when local WAL is flushed
ALTER SYSTEM SET synchronous_commit = 'on';
-- Sync to one named standby
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 (standby1)';
SELECT pg_reload_conf();-- On standby: set application_name to match synchronous_standby_names
ALTER SYSTEM SET cluster_name = 'standby1';
SELECT pg_reload_conf();When to reach for this: You need zero or near-zero committed transaction loss on primary failure and can accept added commit latency.
Measure sync impact and verify partner state:
-- Primary: inspect sync partners
SELECT application_name, sync_state, sync_priority, write_lag, flush_lag, replay_lag
FROM pg_stat_replication;
-- Session-level durability trade-off (bulk load window)
SET synchronous_commit = 'off';
COPY staging.events FROM '/data/events.csv' CSV;
RESET synchronous_commit;# Benchmark commit latency async vs sync (pgbench)
pgbench -h primary.db.internal -U app -c 4 -j 4 -T 30 -S appdb
pgbench -h primary.db.internal -U app -c 4 -j 4 -T 30 -S appdb \
--sync-method=strictWhat this demonstrates:
synchronous_standby_names picks which standbys count toward quorum.sync_state = 'sync' confirms the partner participates in synchronous commits.synchronous_commit = off speeds bulk loads but widens RPO for that session only.COMMIT after local WAL flush (per synchronous_commit). Standby catches up later.COMMIT returns.synchronous_commit levels: off, local, remote_write, remote_apply, on (maps to synchronous_standby_names quorum).FIRST n (...) means any n listed standbys satisfy quorum; ANY n (...) is an alternate quorum style in PostgreSQL 18.| Mode | Typical RPO on primary crash | Commit latency | Failover notes |
|---|---|---|---|
| Async | Last committed seconds of WAL | Lowest | Promote standby; may lose recent commits |
| Sync (1 partner) | Zero committed loss if partner healthy | + RTT to standby | Failover if partner dead blocks commits unless you relax sync |
remote_apply | Zero loss; reads on standby see commit | Highest | Strongest consistency, slowest commits |
Patroni sets synchronous_mode and manages synchronous_standby_names during failover. Test Patroni sync config in staging before production; a lost sync standby can stall writes.
synchronous_standby_names.synchronous_commit = off globally - Fast but RPO widens for all sessions. Fix: Scope to maintenance windows or batch roles only.pg_stat_replication.application_name.| Alternative | Use When | Don't Use When |
|---|---|---|
| Async + frequent base backups | Cross-region DR with loose RPO | Financial ledger needs zero loss |
| Logical replication | Version upgrade, selective tables | You need synchronous physical quorum |
synchronous_commit = remote_write | Balance latency vs durability | You require standby replay visibility before commit |
One local sync partner is the common production pattern. More partners increase latency and failure modes.
No. Only committing transactions wait for standby acknowledgment.
Commits block until quorum is restored or you change synchronous_standby_names. Patroni can demote sync mode automatically.
It waits for standby replay, not just flush. Use only when applications read from standby immediately after commit.
PgBouncer pools connections but does not change PostgreSQL sync semantics. Session settings like synchronous_commit apply per backend connection.
Stack versions: This page was written for PostgreSQL 18.4 (stable 18, maintenance 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x, and PostGIS 3.5+.
Reviewed by Chris St. John·Last updated Jul 18, 2026