Art of Codeartofcode
LLeeaarrnniinngg
BBlloogg
TToooollss
GGaammeess AArreennaa
JJoobbss
LLiivvee CCoouurrsseess

Courses

  • System DesignHigh-level system design, one everyday scene at a time: 30 concepts and 15 interview rounds.712 lessons
All coursesTutorialsMy Learning

Categories

  • 01AI & Tools
  • 02Tutorials
  • 03Engineering
  • 04Reviews
  • 05Build Logs
  • 06Tales of Misfits
  • 07Opinion
  • 08Career
  • 09News

Read & write

All storiesEvery post, newest first.Write for usPublish your stories and earn from what you write.Writer leaderboardsWho is writing the most read posts.

Categories

  • PDF Tools25
  • Development09
  • Utilities10
  • Design04
  • Converters04
  • Generators02

Featured

JSON FormatterFormat, validate and minify JSON.Regex TesterTest patterns against live text.Merge PDFCombine PDFs in your browser.JWT DecoderRead a token’s header and claims.Password GeneratorStrong passwords, generated locally.Gradient GeneratorBuild CSS gradients visually.
All 53 tools

Play a round

DevdleOne developer word a day, six guesses.Python RushClassic snake, with coding icons to eat.Blink or BreakA quick test of your reflexes.
Games Arena

Learn with us

Live CoursesInstructor-led courses. Join a waitlist and be first in when one starts.LearningStructured programming courses with AI assistance and certificates.

System Design

14. Replication

Lesson 15 of 17

14. Replication

1
The picture to keep in your head
2
14.1 Why keep copies of the same data?
3
14.2 How does leader-follower replication work?
4
14.3 Should the leader wait for followers before confirming a write?
5
14.4 What is replication lag, and why does it happen?
6
14.5 How do you stop lag from confusing users?
7
14.6 How do you use read replicas in practice?
8
14.7 What happens when the leader fails?
9
14.8 What is split brain, and how is a leader safely chosen?
10
14.9 When would you have more than one leader?
11
14.10 How does leaderless replication work, and what are quorums?
12
Memory card and where the analogy breaks
13
Practice: five levels
14
Interview questions
15
Solutions
16
Sources
17
Code lab
14. Replication

Solutions

3 min read+10 XP

Solutions

Level 1

reveal

Level 2

reveal

Level 3

reveal

Level 4

reveal

Level 5 (sketch)

reveal

No tracks available

Lofi Player

artofcode

artofcode.in

The den of devs.

Stories, tools, games, and gear for developers.

Read the StoriesEExxpplloorree TToooollss
Art of Codeartofcode

Platform

  • BBlloogg
  • TToooollss
  • GGaammeess AArreennaa
  • CCoouurrsseess
  • LLeeaarrnniinngg
  • CCaammppuuss

Company

  • AAbboouutt UUss
  • JJoobbss && IInntteerrnnsshhiippss
  • CCoonnttaacctt

Legal

  • TTeerrmmss ooff SSeerrvviiccee
  • PPrriivvaaccyy PPoolliiccyy
  • RReeffuunndd PPoolliiccyy

Copyright © 2026 artofcode.in, All Rights Reserved.

IST·--:--

1Show the Level 1 solution
2**A.**
31. **Read-your-writes** failure: the reload hit a lagging replica. Fix: read the user's own content from the leader for a short time after they write, or wait for the replica to reach their write's log position.
42. **Monotonic reads** failure: reads bounced between replicas with different lag. Fix: stick each user to one replica.
53. **Lost writes on async failover.** Fix: synchronous or semi-synchronous replication for orders, so a confirmed order exists on at least two machines.
64. **Split brain.** Fix: majority-based leader election and fencing of the old leader.
7
8**B.**
91. **Payments: synchronous** (or semi-sync to at least one follower). A confirmed payment must survive the leader failing.
102. **Page-view counters: asynchronous.** Losing a few seconds of views is fine; speed matters.
113. **Cross-continent reporting replica: asynchronous.** Waiting for a round trip across continents on every write would slow the whole site, and reports tolerate lag.
Show the Level 2 solution
1. Falling behind at 100 a second: 100 × 600 = **60,000 changes** behind. Catching up at 900 − 500 = 400 a second: 60,000 ÷ 400 = **150 seconds**.
2. About 2 s × 1,000 = **2,000 confirmed writes** could be lost.
3. 5,000 × 0.7 = 3,500 per replica; 20,000 ÷ 3,500 ≈ 5.7 → **6 replicas** (plus one spare is wise).
4. **W = 3, R = 3**: 3 + 3 = 6 > 5, and with 2 nodes down, 3 are still up for both writes and reads.
1Show the Level 3 solution
2Tested solution (Python 3), the key parts:
3
4```python
5class Leader(Node):
6    def __init__(self, name, followers):
7        super().__init__(name)
8        self.log, self.followers = [], followers
9
10    def write(self, key, value):
11        self.log.append((key, value))
12        self.data[key] = value
13        self.applied = len(self.log)
14        return self.applied                          # the write's log position
15
16    def replicate(self, follower, max_entries):     # asynchronous shipping
17        for key, value in self.log[follower.applied:follower.applied + max_entries]:
18            follower.data[key] = value
19            follower.applied += 1
20
21
22def read_your_writes(user_last_lsn, leader, follower, key):
23    if follower.applied >= user_last_lsn:
24        return follower.data.get(key), follower.name
25    return leader.data.get(key), leader.name
26
27
28def quorum_read(replicas, key, r):
29    answers = [rep.store.get(key, (0, None)) for rep in replicas if rep.up][:r]
30    if len(answers) < r:
31        raise RuntimeError("not enough replicas")
32    return max(answers)[1]                           # highest version wins
33```
34
35All checks pass, including the async failover that loses `order:7`, `order:8` and `order:9`. The full file is in `code/ch14_replication.py`.
1Show the Level 4 solution
2**The bug:** it writes to the **primary** and immediately reads from a **replica**, which hasn't received the change yet.
3
41. The `UPDATE` commits on the primary.
52. Replication to the replica takes some milliseconds (more under load).
63. The `SELECT` runs on the replica before the change arrives, and returns the **old address**.
74. The page shows the old address; the user thinks it failed and changes it again.
8
9**Fix 1:** read back from the **primary** (or simply return the value just written):
10
11```python
12def update_address(user_id, address):
13    primary.execute("UPDATE users SET address = %s WHERE id = %s", (address, user_id))
14    return primary.query_one("SELECT address FROM users WHERE id = %s", (user_id,))
15```
16
17**Fix 2: read-your-writes by log position.** Record the log position of the user's write and send that user's reads to the primary until a replica has replayed past it (the chapter's `read_your_writes`). A simpler version: route a user's reads to the primary for a few seconds after any write by them.
1Show the Level 5 (sketch) solution
21. **Layout:** a leader in Mumbai, one **synchronous** (semi-sync) follower in another Mumbai availability zone (no lost orders on failover), two or more **asynchronous** read replicas in Mumbai for browsing, and one asynchronous replica in Frankfurt for European reads.
32. **Routing:** writes, carts and "my orders" go to the leader (or use read-your-writes by log position); book pages, search and recommendations go to replicas, with each user stuck to one replica; reports use a separate replica.
43. **Failover:** Patroni or a managed service, using a 3-node etcd cluster for majority-based election; promote the synchronous follower (it has every confirmed order); fence the old leader by term number; apps reconnect through a stable endpoint; retries with backoff.
54. **European writes:** go to the Mumbai leader (one leader per record, no conflicts), accepting extra latency on checkout; browsing reads are served from the Frankfurt replica. Multi-leader would cut write latency but bring conflicts, not worth it for orders.
65. **Monitor:** replication lag per replica, synchronous standby health, failover events, read/write split ratios, leader CPU and write rate, and backup success (replicas aren't backups).