Question Answered: When the primary commits, does it wait for replicas or not?
Synchronous: Wait for replica acknowledgement before the commit returns
Asynchronous: Commit returns right after the local write. Replicas catch up later
Semi-Synchronous: MySQL’s middle ground. Waits for a replica, but can fall back to async
Deep Dive: Priority vs Quorum modes are covered in Synchronous Replication - Priority vs Quorum
Synchronous Replication
How It Works
Write Process: Primary flushes the commit to its own WAL, then waits for the chosen replica(s) to acknowledge
Blocking: The client’s COMMIT blocks until the acknowledgements arrive
Which Replicas: Chosen by mode — Priority (FIRST N, specific ranked standbys) or Quorum (ANY N of a group)
How Far: Set by synchronous_commit (Postgres) — the replica acks after write, flush, or replay
Characteristics
Durability: A committed transaction exists on the primary and on N replicas
Data Loss: No loss of acknowledged commits if the primary dies — as long assynchronous_commit is on or remote_apply, and you fail over to a replica that acked
Read Consistency: Durability ≠ read-after-write. With the default on, the replica has flushed WAL but may not have replayed it yet, so reads on the replica can still be stale. Use remote_apply if replica reads must see the commit
Latency: Every commit pays the network round trip plus the replica’s WAL flush
Availability: If fewer than N sync replicas are reachable, writes hang (Postgres never falls back to async by itself). Keep spare standbys (e.g. ANY 1 of 2)
Trade-offs
Pros: No data loss on failover, safe promotion, durable copies on multiple nodes
Cons: Slower commits, row locks held longer (hot rows hurt the most), writes block when the sync replicas are down
Use Cases
Financial transactions, payments, ledgers
Critical data where losing an acknowledged write is unacceptable
Systems that need automatic failover without data loss
Asynchronous Replication
How It Works
Write Process: Primary commits right after the local WAL flush
Non-blocking: The transaction completes without waiting for replicas
Replication: WAL is streamed to replicas in the background
Characteristics
Consistency: Eventual — replicas lag behind (usually milliseconds, can be minutes under load)
Durability: Only guaranteed on the primary at commit time
Latency: Low — same as a standalone database
Data Loss: Commits not yet shipped are lost if the primary dies and a replica is promoted
Availability: A replica failure never blocks writes
Trade-offs
Pros: Fast writes, replicas can be far away (cross-region), replica problems don’t affect the primary
Cons: Replication lag, stale reads, possible data loss on failover
Use Cases
Read scaling for read-heavy apps that tolerate slight lag
Cross-region DR copies where sync latency would be too high
Analytics/reporting replicas
Comparison Table
Aspect
Synchronous
Asynchronous
Write Latency
High (+ RTT + replica flush per commit)
Low (local only)
Durability at commit
Primary + N replicas
Primary only
Data Loss on failover
None (with on / remote_apply)
Possible (unshipped WAL)
Replica reads
Stale possible unless remote_apply
Stale possible (lag)
Replica failure
Can block writes if < N available
No effect on writes
Distance
Same region / nearby AZs
Anywhere, including cross-region
Complexity
Moderate (need spare standbys)
Simple
Best For
Critical data
Performance, read scaling, DR
Semi-Synchronous Replication (MySQL)
How It Works
Term: A MySQL feature. In Postgres, FIRST 1 / ANY 1 is simply called synchronous replication
Wait: Source waits until at least rpl_semi_sync_source_wait_for_replica_count replicas (default 1) have received the event into their relay log (not applied it)
Wait Point: AFTER_SYNC (default since 5.7, “lossless”) — waits before the commit is visible to other sessions. AFTER_COMMIT (old) — commit is visible before the replica acks
Fallback: If no ack arrives within rpl_semi_sync_source_timeout (default 10s), the source silently switches to async. It switches back when replicas catch up
Trade-offs
Pros: Close to sync durability, writes never block forever
Cons: During a fallback window you are effectively async — data loss is possible on failover. Monitor Rpl_semi_sync_source_status
Postgres vs MySQL
Aspect
Postgres Sync
MySQL Semi-Sync
Ack means
Flushed (on) or replayed (remote_apply)
Received in relay log
No replica available
Writes block
Falls back to async after timeout
Choose replicas
FIRST N / ANY N lists
Any N replicas (count only)
Configuration Examples
PostgreSQL (postgresql.conf or ALTER SYSTEM, reload is enough)
-- Priority: wait for standby1 (standby2 takes over if it disconnects)ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 (standby1, standby2)';-- Quorum: wait for any 2 of 3ALTER SYSTEM SET synchronous_standby_names = 'ANY 2 (standby1, standby2, standby3)';-- Asynchronous (default)ALTER SYSTEM SET synchronous_standby_names = '';-- How far the standby must go before acking: off | local | remote_write | on | remote_applyALTER SYSTEM SET synchronous_commit = 'on';SELECT pg_reload_conf();
MySQL 8.0.26+ (semi-sync)
-- On the sourceINSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';SET GLOBAL rpl_semi_sync_source_enabled = 1;SET GLOBAL rpl_semi_sync_source_timeout = 10000; -- ms before falling back to asyncSET GLOBAL rpl_semi_sync_source_wait_point = 'AFTER_SYNC';-- On each replicaINSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so';SET GLOBAL rpl_semi_sync_replica_enabled = 1;STOP REPLICA IO_THREAD; START REPLICA IO_THREAD;
Older versions use master/slave names: semisync_master.so, rpl_semi_sync_master_enabled.
MySQL Group Replication is a different system (Paxos-based, every transaction is certified by a majority of the group).
Decision Framework
Choose Synchronous When
Losing an acknowledged write is unacceptable
Replicas are close (same region) so the latency is affordable
You can run at least N + 1 standbys so one failure doesn’t block writes
Choose Asynchronous When
Write latency/throughput matters most
Replicas are far away (cross-region DR)
A few seconds of lost writes on a rare failover is acceptable
Mix Them (common in production)
1–2 nearby sync standbys (ANY 1) for zero-loss failover, plus async replicas for read scaling and cross-region DR
Per-transaction override for low-value writes: SET LOCAL synchronous_commit = local;
Summary
Synchronous: Durable on N replicas at commit, slower writes, blocks if not enough replicas are up (Postgres)
Asynchronous: Fast writes, replication lag, possible data loss on failover
Semi-Synchronous (MySQL): Waits for receipt, falls back to async on timeout
Durability ≠ read consistency: Sync replication alone doesn’t make replica reads fresh — that needs remote_apply
Key Trade-off: Durability vs write latency and availability