Overview

  • 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 as synchronous_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

AspectSynchronousAsynchronous
Write LatencyHigh (+ RTT + replica flush per commit)Low (local only)
Durability at commitPrimary + N replicasPrimary only
Data Loss on failoverNone (with on / remote_apply)Possible (unshipped WAL)
Replica readsStale possible unless remote_applyStale possible (lag)
Replica failureCan block writes if < N availableNo effect on writes
DistanceSame region / nearby AZsAnywhere, including cross-region
ComplexityModerate (need spare standbys)Simple
Best ForCritical dataPerformance, 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

AspectPostgres SyncMySQL Semi-Sync
Ack meansFlushed (on) or replayed (remote_apply)Received in relay log
No replica availableWrites blockFalls back to async after timeout
Choose replicasFIRST N / ANY N listsAny 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 3
ALTER 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_apply
ALTER SYSTEM SET synchronous_commit = 'on';
 
SELECT pg_reload_conf();

MySQL 8.0.26+ (semi-sync)

-- On the source
INSTALL 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 async
SET GLOBAL rpl_semi_sync_source_wait_point = 'AFTER_SYNC';
 
-- On each replica
INSTALL 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