Ecommet
Topic 29 of 75

Database Replication

Replication keeps copies of your data on several machines for availability and read capacity. Learn leader-follower and multi-leader setups, synchronous vs asynchronous copies, replication lag and failover.

Intermediate 6 min read 4 quiz questions

Jump to the quiz

In a nutshell

  • Leader-follower: all writes go to the leader, which streams changes to followers that serve reads.
  • Asynchronous replication is fast but a failover can lose recent writes; synchronous waits for a copy, adding latency.
  • Replication lag means a follower can be behind: users may not see their own changes unless you route carefully.
  • Multi-leader and leaderless setups accept writes in several places, at the cost of resolving conflicts.

Leader and followers

Leader-follower replication

Leader-follower replication App servers → Leader: writes Leader → Follower 1: change log Leader → Follower 2 App servers → Follower 2: reads App serversLeaderreads + writesFollower 1readsFollower 2readswriteschange logreads

All steps Writes go to one leader. Followers apply its change log and serve reads.

Diagram as text
  1. Every write goes to the leader.
  2. The leader streams its change log to the followers, which apply it in order.
  3. Reads can go to followers, spreading load across machines.
  • More read capacity: most apps read far more than they write; add followers to serve the reads.
  • Availability: if the leader dies, a follower is promoted (failover).
  • Locality: put a follower near users in another region for fast local reads.
  • Safe heavy queries: run analytics and backups on a follower without slowing the leader.

Synchronous or asynchronous

A common middle ground is semi-synchronous: one follower is synchronous, the rest asynchronous.
SynchronousAsynchronous
Commit waits forAt least one follower to confirmOnly the leader's own disk
Write latencyHigher (a network round trip)Lowest
Leader diesNo committed data lostWrites not yet copied are lost
Follower slow or downWrites stall (unless another follower confirms)No effect on writes

Replication lag

Asynchronous followers are usually milliseconds behind, but under load or network trouble it can be seconds or more. That causes visible bugs:

Where did my comment go?

Where did my comment go? User → Leader: post comment Leader → User: saved User → Follower: reload page Follower → User: no comment yet! Leader → Follower: change arrives (late) UserLeaderFollowerpost commentsavedreload pageno comment yet!change arrives (late)

All steps The write reached the leader, but the read went to a follower that had not caught up yet.

Diagram as text
  1. The user posts a comment; it is written to the leader.
  2. The leader confirms.
  3. The page reloads and reads from a follower.
  4. The follower is a moment behind and does not have the comment.
  5. The change arrives shortly after, but the user already thinks it was lost.

Fixes for read-your-own-writes: read from the leader for anything the user just changed (or for a few seconds after any write by that user), or track the log position of the user's last write and only use followers that have reached it.

Route a user's reads to the leader for a short window after they write

Java
import java.util.*;

class ReadRouter {
    private final double stickySeconds;
    private final Map<String, Double> lastWrite = new HashMap<>();

    ReadRouter(double stickySeconds) {
        this.stickySeconds = stickySeconds;
    }

    synchronized void recordWrite(String userId, double now) {
        lastWrite.put(userId, now);
    }

    synchronized String readTarget(String userId, double now) {
        Double last = lastWrite.get(userId);
        if (last != null && now - last < stickySeconds) {
            return "leader";
        }
        return "follower";
    }
}
Python
import threading

class ReadRouter:
    def __init__(self, sticky_seconds):
        self.sticky = sticky_seconds
        self.last_write = {}  # user id -> time of their last write
        self.lock = threading.Lock()

    def record_write(self, user_id, now):
        with self.lock:
            self.last_write[user_id] = now

    def read_target(self, user_id, now):
        with self.lock:
            last = self.last_write.get(user_id)
            if last is not None and now - last < self.sticky:
                return "leader"
            return "follower"

Failover and multi-leader

Failover sounds simple (promote a follower) but has sharp edges: detecting that the leader is really dead and not just slow, choosing the most up-to-date follower, redirecting writes, and making sure the old leader does not come back still thinking it is the leader (split brain). Managed databases automate this, usually in tens of seconds.

Multi-leader replication accepts writes in several places (for example one leader per region) and syncs them. Writes are fast everywhere, but two leaders can change the same record at once, so you need a conflict resolution rule: last write wins (loses data), merge the values, or let the application decide. Leaderless systems (Dynamo-style, such as Cassandra) write to several replicas and use quorums instead.

Common mistakes

  • Reading from followers right after a write and showing users stale data.
  • Treating followers as backups: a bad DELETE replicates to all of them instantly. Keep real backups too.
  • Assuming failover loses nothing while using asynchronous replication.
  • Choosing multi-leader without a plan for conflicts.

Interview questions

Try answering out loud before you open each one.

Reads are overloading the database. What do you do?

Add a cache for hot reads and add read replicas, routing read-only queries to them. Handle replication lag: read-your-own-writes from the leader, and keep queries needing fresh data on the leader. If writes are the bottleneck, replicas do not help; look at sharding.

What happens when the leader fails?

Failure is detected (missed heartbeats), the most up-to-date follower is promoted, clients are redirected (DNS, proxy or a config service), and the old leader is fenced off so it cannot accept writes if it returns. With asynchronous replication, writes not yet copied may be lost.

Check yourself

1. In leader-follower replication, where do writes go?
Show the answer

Answer: The leader only. One leader orders all writes; followers copy them.

2. A user posts and immediately does not see the post. Likely cause?
Show the answer

Answer: Replication lag on the follower serving the read. The follower has not applied the write yet.

3. What is the risk of asynchronous replication during failover?
Show the answer

Answer: Recent writes not yet copied can be lost. Writes confirmed by the old leader but not yet replicated disappear.

4. Read replicas help most when…
Show the answer

Answer: Reads are the bottleneck. Every replica still applies every write; replicas add read capacity.

Further reading

Your notes

Saved in this browser as you type.

Finished this topic?

Mark it read to track your progress, then carry on with the next one.

Next topic