Back to Advanced: Replication, Consistency, CAP
Q4Question 4 of 5

Synchronous vs asynchronous replication

Key Concepts
  • Synchronous replication makes the primary wait until the replica confirms the write is durable before acknowledging the client.
  • Recovery Point Objective is zero with synchronous replication: no acknowledged transaction is lost on failover.
  • Asynchronous replication acknowledges the client immediately and ships changes to replicas in the background.
  • Asynchronous replication has lower latency but a replication-lag window where a crash loses not-yet-shipped transactions.
  • Semi-synchronous or quorum replication waits for any one of several replicas, balancing durability and availability.
  • For banking ledgers, synchronous or quorum replication is used because losing a committed transfer is unacceptable.
  • Analytics and reporting replicas typically use asynchronous replication because slight lag is tolerable.

Definition

Synchronous trades latency for zero data loss; asynchronous trades a small data-loss window for speed.
  • Synchronous replication – the primary waits until at least one replica confirms the write is durable before acknowledging the client; RPO is zero.
  • Asynchronous replication – the primary acknowledges the client immediately and ships changes to replicas in the background; lower latency but a data-loss window.
  • RPO (Recovery Point Objective) – the maximum amount of data that can be lost on failover; zero for synchronous, non-zero for asynchronous.
  • Semi-synchronous / quorum – waits for any one of several replicas to confirm, so a single slow replica does not block.
  • Replication lag – the delay between a write on the primary and its visibility on a replica.

When Rajesh transfers money at National Bank of India, synchronous replication is like the teller refusing to hand over the receipt until a second branch has also recorded the transaction: safe but slower. Asynchronous is like handing the receipt immediately and faxing the other branch a moment later: fast, but if the main branch burns down in that moment, the second branch missed the last entry.

Understanding the Concepts

What is synchronous replication?

In synchronous replication, the primary applies the write locally, sends the change (WAL record) to the replica, and blocks the client's commit until the replica acknowledges durability. If the primary dies, a promoted synchronous replica has every acknowledged transaction.

SQL
-- PostgreSQL: configure synchronous replication
-- postgresql.conf on primary
-- synchronous_commit = on
-- synchronous_standby_names = 'replica1'

-- When Rajesh's transfer commits, the primary waits for
-- replica1 to confirm before returning success to the app.

BEGIN;
UPDATE accounts SET balance = balance - 25000.00
WHERE account_id = 'SAV2001';
UPDATE accounts SET balance = balance + 25000.00
WHERE account_id = 'SAV2002';
COMMIT;  -- blocks until replica1 confirms
DIAGRAM
Synchronous Replication Timeline:

  App          Primary           Replica
  │            │                 │
  │──COMMIT──► │                 │
  │            │──WAL record───► │
  │            │                 │──write to disk
  │            │ ◄──ACK──────── │
  │ ◄──OK──── │                 │
  │            │                 │
  Latency = local commit + network round trip + replica write
  RPO = 0 (no data loss on failover)

What is asynchronous replication?

In asynchronous replication, the primary commits and acknowledges the client immediately, then streams changes to replicas. The latency is just the local commit, but there is replication lag.

SQL
-- PostgreSQL: asynchronous replication (default)
-- synchronous_commit = off (or no synchronous_standby_names)

BEGIN;
UPDATE accounts SET balance = balance - 25000.00
WHERE account_id = 'SAV2001';
COMMIT;  -- returns immediately, WAL shipped in background
DIAGRAM
Asynchronous Replication Timeline:

  App          Primary           Replica
  │            │                 │
  │──COMMIT──► │                 │
  │ ◄──OK──── │                 │
  │            │──WAL record───► │  (background)
  │            │                 │──write to disk
  │            │                 │
  Latency = local commit only
  RPO > 0 (lag window: data loss possible on crash)

How do synchronous and asynchronous replication compare?

| Aspect | Synchronous | Asynchronous |
|---|---|---|
| Client latency | Higher (+ network round trip) | Lower (local commit only) |
| Data loss on failover | Zero (RPO = 0) | Possible (RPO > 0) |
| Replica availability | If replica is down, primary may stall | Primary unaffected |
| Use case | Ledger, money, compliance | Analytics, reporting, read scaling |
| Throughput | Lower (bound by network) | Higher (fire-and-forget) |

JAVA
package com.bank.service;

import java.math.BigDecimal;
import java.sql.*;
import java.util.logging.Logger;

public class ReplicationDemoService {

    private static final Logger LOG = Logger.getLogger(
        ReplicationDemoService.class.getName());

    private final Connection primaryConn;
    private final Connection replicaConn;

    public ReplicationDemoService(Connection primaryConn, Connection replicaConn) {
        this.primaryConn = primaryConn;
        this.replicaConn = replicaConn;
    }

    public void demonstrateLag(String accountId) throws SQLException {
        // Write to primary
        String updateSql = "UPDATE accounts SET balance = balance + 1000.00 "
                         + "WHERE account_id = ?";
        try (PreparedStatement ps = primaryConn.prepareStatement(updateSql)) {
            ps.setString(1, accountId);
            ps.executeUpdate();
        }
        LOG.info("Committed on primary");

        // Immediately read from async replica: may see stale data
        String selectSql = "SELECT balance FROM accounts WHERE account_id = ?";
        try (PreparedStatement ps = replicaConn.prepareStatement(selectSql)) {
            ps.setString(1, accountId);
            try (ResultSet rs = ps.executeQuery()) {
                if (rs.next()) {
                    BigDecimal balance = rs.getBigDecimal("balance");
                    LOG.info("Replica balance: " + balance
                        + " (may be stale with async replication)");
                }
            }
        }
    }
}

What is semi-synchronous or quorum replication?

Semi-synchronous replication waits for any one of several replicas to confirm, so a single slow or failed replica does not block the primary. This balances durability and availability.

SQL
-- PostgreSQL: quorum-based synchronous replication
-- Wait for ANY 1 of 3 replicas to confirm
-- synchronous_standby_names = 'ANY 1 (replica1, replica2, replica3)'

-- If replica1 is slow, the primary gets an ACK from replica2
-- and returns success. No single replica can stall the primary.
DIAGRAM
Quorum Replication:

  Primary ──WAL──► replica1 (slow, no ACK yet)
           ──WAL──► replica2 ──ACK──► Primary commits
           ──WAL──► replica3

  Primary needs ANY 1 ACK. replica2 responded first.
  Result: durable on primary + replica2, no stall.

When should you use each replication mode?

Use synchronous or quorum replication for data where losing a committed transaction is unacceptable: the balance ledger, loan disbursements, and compliance records. Use asynchronous replication for read scaling and analytics where slight lag is tolerable.

DIAGRAM
National Bank of India Replication Strategy:

  Data Type              Replication Mode     Reason
  ─────────────────────  ──────────────────   ─────────────────────
  Account ledger         Synchronous (quorum) Zero data loss
  Loan disbursements     Synchronous          Compliance requirement
  Analytics warehouse    Asynchronous         Lag is acceptable
  Reporting dashboards   Asynchronous         Read scaling
  DR site standby        Synchronous          Fast failover

What happens during failover with each mode?

With synchronous replication, the promoted replica has every acknowledged transaction. With asynchronous replication, the promoted replica may be missing the last few transactions.

TEXT
Failover Scenario:

  Synchronous:                      Asynchronous:
  Primary crashes after commit.     Primary crashes after commit.
  Replica has the commit.           Replica may NOT have the commit.
  Promote replica: no data loss.    Promote replica: last N txns lost.

  Rajesh's transfer of 25000:       Rajesh's transfer of 25000:
  Replica shows 25000 debited.      Replica may show old balance.
  RPO = 0.                          RPO = replication lag.

What are common mistakes with replication?

The most common mistake is assuming asynchronous replication means zero data loss. In reality, any committed transaction on the primary that has not yet been shipped to the replica is lost during failover. Another mistake is reading from a replica and expecting it to reflect the latest write.

JAVA
package com.bank.service;

// WRONG: write then immediately read from replica
// The replica may not have the write yet
public void transferAndConfirm(String fromId, String toId, java.math.BigDecimal amount) {
    transferService.transfer(fromId, toId, amount);  // writes to primary
    var balance = replicaRepo.getBalance(fromId);     // reads from replica
    // balance may still show the old value!
}

// CORRECT: read from primary for consistency-critical reads
public void transferAndConfirm(String fromId, String toId, java.math.BigDecimal amount) {
    transferService.transfer(fromId, toId, amount);  // writes to primary
    var balance = primaryRepo.getBalance(fromId);     // reads from primary
}

What should a senior engineer know?

A senior engineer should design failover to detect and bound the lag. They should know that synchronous replication can stall if the sole synchronous replica goes down, so quorum or fallback-to-async configurations are important for production.

SQL
-- PostgreSQL: fallback behavior
-- If synchronous_standby_names lists one replica and it goes down,
-- the primary stalls on every COMMIT (waiting for an ACK that never comes).
-- Fix: use quorum (ANY 1 of N) or set synchronous_commit = local
-- as a manual emergency fallback.

-- Monitor replication lag
SELECT client_addr,
       state,
       sent_lsn,
       write_lsn,
       flush_lsn,
       replay_lsn,
       sent_lsn - replay_lsn AS lag_bytes
FROM pg_stat_replication;

Visual Overview

DIAGRAM
┌──────────────────────────────────────────────────────┐
│   Synchronous vs Asynchronous Replication             │
├──────────────────────────────────────────────────────┤
│                                                      │
│  SYNCHRONOUS:                                        │
│  App ──COMMIT──► Primary ──WAL──► Replica             │
│                      │               │               │
│                      │    wait...    │               │
│                      │ ◄────ACK───── │               │
│  App ◄──OK────── Primary             │               │
│                                                      │
│  Latency: local + network + replica flush            │
│  RPO: 0 (zero data loss)                             │
│                                                      │
│  ASYNCHRONOUS:                                       │
│  App ──COMMIT──► Primary                             │
│  App ◄──OK────── Primary ──WAL──► Replica             │
│                      (background)    │               │
│                                      │               │
│  Latency: local commit only                          │
│  RPO: > 0 (lag window)                               │
│                                                      │
│  SEMI-SYNCHRONOUS / QUORUM:                          │
│  Primary ──WAL──► replica1 (slow)                    │
│           ──WAL──► replica2 ──ACK──► Primary commits │
│           ──WAL──► replica3                          │
│  Wait for ANY 1 of N replicas                        │
└──────────────────────────────────────────────────────┘

Key Takeaway

Replication copies writes from a primary to one or more replicas, and the key distinction is when the client is told the commit succeeded. In synchronous replication the primary waits until at least one replica confirms the change is durable before acknowledging, which gives a Recovery Point Objective of zero: no acknowledged transaction is lost on failover. The cost is one network round trip of latency per commit. In asynchronous replication the primary acknowledges immediately and ships the change in the background, so latency is just the local commit, but there is a replication-lag window where a crash loses the not-yet-shipped transactions.

At the National Bank of India, Pankaj applies this per data class. The ledger, where losing a committed transfer is unacceptable, uses synchronous or quorum replication to the disaster-recovery replica so the RPO is zero. Analytics and reporting read from an asynchronous replica that tolerates a little lag in exchange for not slowing down writes.

In practice, the team uses a semi-synchronous or quorum setup that waits for any one of several replicas, so a single slow replica does not stall every commit. Monitoring replication lag with pg_stat_replication is essential for detecting drift before it becomes a problem during failover.

The danger of synchronous replication is that if the sole synchronous replica goes down, the primary stalls on every COMMIT. The fix is quorum configuration or a manual fallback to local commit mode in emergencies.

Remember one sentence: synchronous trades latency for zero data loss, and asynchronous trades a small data-loss window for speed.

---

Share
Use ← → arrow keys to navigate