2:13 am: “orders-db primary down”
On the internship’s on-call channel at 2:13 am an alert fires: “orders-db primary down”. Twenty-eight seconds later: “failover complete, replica-1 promoted”. In the morning Kabir reads the incident note. One line worries him: “1 order acknowledged in the last second before the crash needs manual reconciliation.”
Sir, the database died and the app came back in 28 seconds. How? And how can an order be “acknowledged” and then go missing?
Because the data was replicated: the same data was kept on three machines. One, the leader, takes all writes; the two followers copy everything it does. When the leader died, a follower was promoted.
So why was one order missing?
Because the followers copy slightly later, a fraction of a second behind. The leader had said “OK” to that order before any follower had copied it. That is asynchronous replication: fast, but a crash can lose the last moment of writes.
Then why not wait for the followers every time?
That’s synchronous replication: safer, but every write waits for the slowest copy. Today you’ll see this trade-off, watch a failover step by step, learn what Kafka’s acks=all really means, and see the scariest failure of all: two leaders at once, called split brain.
What is replication?
Replication is maintaining copies of the same data on multiple nodes to provide fault tolerance, high availability, durability, read scalability and lower latency. In leader-based (primary–replica) replication one node accepts writes and streams changes to followers; replication can be synchronous (the write is acknowledged after replicas confirm), asynchronous (acknowledged immediately, replicas apply later) or semi-synchronous. Multi-leader and leaderless replication allow writes at several nodes and must resolve conflicts. The number of copies is the replication factor.
Replication means keeping the same data on several machines. Usually one machine (the leader) takes the changes and the others (followers) copy them. If the leader breaks, a follower takes over. Copies can be updated straight away (safe but slower) or a moment later (fast but a crash can lose the last few changes).
Words you’ll meet in this lesson
Replication in tools you will use
| HDFS | every block stored 3 times by default, on different racks where possible |
|---|---|
| Kafka | each partition has a leader and followers; in-sync replicas (ISR); producers choose acks=0, 1 or all |
| PostgreSQL / MySQL | primary with streaming read replicas; sync or async; managed services automate failover |
| Cassandra | leaderless; replication factor per keyspace; consistency level chosen per query |
| Cloud object storage | copies or erasure-coded pieces across availability zones, handled for you |
Replication at three levels
Beginner Photocopies of the class notes
- Replication is keeping copies of the same data on several machines, like photocopying the topper’s notes for three friends. If one copy is lost, the others still have it.
- Why: survive failures (availability), never lose data (durability), let more people read at once (read scaling), and keep copies close to users (lower latency).
- Leader and followers: one person writes the notes (the leader); the others copy from them (followers). Everyone asks the leader to change something.
- Not a backup: if you delete a page by mistake, the deletion is copied too. Replication protects against machines failing, backups against mistakes.
Intermediate Sync vs async, lag and read replicas
- Synchronous: the leader confirms a write only after followers have it. No loss on leader failure, but writes are slower and a slow follower slows everyone.
- Asynchronous: the leader confirms immediately and followers catch up later. Fast, but the last moments of writes can be lost in a crash, and followers lag behind.
- Semi-synchronous: wait for one follower, not all. A common middle ground.
- Replication lag: a read from a follower may show old data. Problems this causes: a user doesn’t see their own update (read-your-writes), or sees data jump backwards when reads hit different replicas (monotonic reads).
- Replication factor: how many copies. HDFS blocks: 3. Kafka partitions: commonly 3, with
min.insync.replicas=2and producers usingacks=all.
Advanced Failover, split brain and consensus
- Failover: detect that the leader is dead (heartbeat timeouts), choose the most up-to-date follower, promote it, and redirect clients. Too short a timeout causes needless failovers; too long means longer outages.
- RPO and RTO: Recovery Point Objective = how much recent data you can afford to lose (async replication: seconds); Recovery Time Objective = how long you can be down (automatic failover: tens of seconds).
- Split brain: a network partition makes the old leader and a newly elected one both accept writes. Prevent it with majority quorums (only the side with more than half the nodes can elect a leader) and fencing tokens (increasing epoch numbers; storage rejects writes from older epochs).
- Consensus: algorithms like Raft and Paxos (used in etcd, ZooKeeper and Kafka’s KRaft) let nodes agree on one leader and one order of writes despite failures.
- Multi-leader and leaderless: several nodes accept writes (multi-region apps, Cassandra/Dynamo-style quorums with R + W > N). Concurrent writes conflict and must be resolved: last-write-wins (can silently drop data), version vectors, or CRDTs that merge automatically.
Exam tip: Define replication, list its benefits (availability, durability, read scaling, latency), and compare synchronous vs asynchronous in a table (latency, data-loss risk, availability). Name the three architectures (single-leader, multi-leader, leaderless) with one example each, and mention replication lag and failover.
Leaders, followers and how they sync
Single-leader
One leader takes all writes; followers copy and can serve reads. Simple and consistent ordering. PostgreSQL, MySQL, Kafka partitions, HDFS NameNode HA.
Most commonMulti-leader
Several leaders (often one per region) accept writes and sync with each other. Good for multi-region apps; conflicts must be resolved.
Multi-regionLeaderless
Clients write to several replicas and read from several; quorums (R + W > N) give consistency. Cassandra, DynamoDB-style stores.
QuorumsSynchronous vs asynchronous
| Synchronous | Asynchronous | Semi-synchronous | |
|---|---|---|---|
| Write acknowledged | After all chosen replicas confirm | Immediately by the leader | After at least one replica confirms |
| Write latency | Highest (waits for slowest) | Lowest | Medium |
| Data loss if leader dies | None | Last moments of writes | None if that replica survives |
| Effect of a slow replica | Slows every write | Only increases lag | Tolerates slow extra replicas |
| Typical use | Payments within one region | Read replicas, cross-region copies | Default for many critical databases |
Replication is not a backup. A bad DELETE or a bug that corrupts rows is replicated to every copy within seconds. Keep point-in-time backups or snapshots too, and test restoring them.
One write, three copies, one failure
The leader writes and acknowledges
Every write goes to the leader, which appends it to its replication log. With asynchronous replication it says “OK” right away, before any follower has the change.leader, followers = [], {"F1": [], "F2": []} def write(entry): leader.append(entry) # 1. leader appends to its log return "OK" # 2. async: acknowledge immediately print(write("order O1"), write("order O2")) print("leader:", leader, "| F1:", followers["F1"])OK OK leader: ['order O1', 'order O2'] | F1: []Followers replay the log
Followers receive the log entries in the same order and apply them, so they end up with identical data. Order matters: “add ₹100” then “set to ₹0” gives a different result in the other order.leader = ["order O1", "order O2"] followers = {"F1": [], "F2": []} for f in followers: # 3. followers copy the log in order followers[f].extend(leader) print(followers){'F1': ['order O1', 'order O2'], 'F2': ['order O1', 'order O2']}Reads from a follower can be stale
Followers are good for spreading read load, but they can be behind. A user who just changed their address might read the old one from a lagging follower.leader = ["O1", "O2", "O3", "O4"] f2 = ["O1", "O2"] # F2 is two entries behind print("read from leader:", len(leader), "orders | read from F2:", len(f2), "orders") print("lag:", len(leader) - len(f2), "entries")read from leader: 4 orders | read from F2: 2 orders lag: 2 entriesThe leader fails: promote the best follower
The most up-to-date follower becomes leader. O4 had been acknowledged by the old leader but never reached a follower, so it is lost: the cost of asynchronous replication.logs = {"F1": ["O1", "O2", "O3"], "F2": ["O1", "O2"]} acked = ["O1", "O2", "O3", "O4"] # the leader had said OK to O4 new_leader = max(logs, key=lambda f: len(logs[f])) print("promote:", new_leader, "| lost:", [o for o in acked if o not in logs[new_leader]])promote: F1 | lost: ['O4']Redirect clients and rejoin
Clients learn the new leader’s address (through a DNS change, a proxy or a coordination service). When the old leader comes back, it must rejoin as a follower and discard writes the new leader never had.
If the old leader came back still believing it was the leader, there would be two leaders: split brain (scenario 3).Choose the safety level per data
Payments: synchronous or semi-synchronous replication within a region. Analytics replicas and cross-region copies: asynchronous. Kafka:
Replication is a dial between speed and safety. Choose it per dataset, based on how much loss (RPO) and downtime (RTO) the business can accept.acks=allwithmin.insync.replicas=2for important topics.
Riya changes her address: which copy answers?
Step through the six frames. Left: Riya updating and re-checking her address. Right: the leader and followers, and which copy serves each request.
- Riya changes her delivery address to Baner and taps Save.
- The app confirms: address saved.
- She refreshes her profile to double-check.
- It shows the old Kothrud address. She panics: did the change fail?
- After the fix, she refreshes again.
- The new address appears, every time.
- The update is sent to the leader database.
- The leader stores it and acknowledges immediately. Replication to followers is asynchronous.
- Follower 1 has applied the change; Follower 2 is still a second behind.
- Her profile read is load-balanced to Follower 2, which hasn’t applied the change yet. She sees stale data.
- Fix for read-your-writes: for a short time after a user writes, send that user’s reads to the leader (or to a replica known to be up to date).
- Now she always sees her own changes, while other users' reads still spread across followers.
Real-time scenarios: copies under failure
Three live scenarios: an automatic failover at 2 am, what Kafka’s acks setting really guarantees, and an advanced look at split brain and how fencing prevents it.
Real-time scenario 12:13 am: the leader dies
Three database nodes: A leads, B and C follow. At 2:13 am A's disk fails. Watch an automatic failover step by step, and where data can be lost.
- Normally Node A is the leader. B and C copy its log and everyone exchanges heartbeats every second.
- A's disk fails. Its heartbeats stop and client writes start failing.
- After a timeout (here 10 seconds) B and C compare how far their logs go. B is the most up to date. Together they form a majority of the three nodes, so they are allowed to elect a new leader.
- B is promoted and clients are redirected to it; writes resume after about 20–30 seconds in total. With asynchronous replication, the last writes A had acknowledged but not yet sent are lost.
- When A is repaired, it rejoins as a follower, discards anything B never had, and copies from B.
Kafka acks: when is a message really safe?
A payments service writes events to a Kafka topic with replication factor 3. The producer setting acks decides when the producer is told “done”. Watch what each setting means when a broker crashes.
- acks=0: the producer sends and moves on without any confirmation. Fastest, but messages can be lost silently.
- acks=1: the producer gets “OK” once the partition leader has written the message, before followers have copied it.
- If the leader crashes at that moment, a follower becomes leader without the message. The producer was told it succeeded, but the message is gone.
- acks=all: the producer gets “OK” only when all in-sync replicas have the message. With
min.insync.replicas=2, at least two copies must exist or the write is refused. - Now a leader crash loses nothing that was acknowledged. The cost is a few milliseconds more per write. For payments, orders and anything you can’t recreate, use acks=all.
Split brain: two leaders at once
The worst replication failure is not a crash but a network split, where the old leader keeps running and a new one is elected. Watch how majorities and fencing tokens keep only one leader in charge.
- Node A is the leader in “epoch 1”; B and C follow.
- A network fault separates A from B and C. A is alive, and some clients on its side can still send it writes.
- B and C stop hearing from A and, being two of three nodes, elect B as leader in epoch 2. If A keeps accepting writes, there are two leaders and two diverging versions of the data: split brain.
- Majority quorum: a leader must be able to reach a majority. A can reach only itself (1 of 3), so it steps down and refuses writes. This is why clusters use odd numbers of nodes: 3 or 5.
- Fencing tokens: every new leader gets a higher epoch number, and storage rejects writes carrying an older one. Consensus systems such as Raft (etcd, Kafka KRaft) and ZooKeeper provide exactly these guarantees.
Replication at work
1. Managed databases with standby replicas
Cloud databases (such as Amazon RDS Multi-AZ or Azure SQL) keep a synchronous standby in another zone and fail over automatically, typically within a minute or two.
2. Read replicas for reports and dashboards
Reporting and analytics queries are sent to read replicas so they don’t slow down the primary that serves the app. Reports may lag by a few seconds, which is fine for them.
3. Kafka for payments and orders
Fintech and e-commerce teams run critical topics with replication factor 3, min.insync.replicas=2 and acks=all, so a broker failure loses no acknowledged events.
4. Disaster recovery across regions
Banks and large platforms keep an asynchronous copy in another region (for example Mumbai and Hyderabad) and rehearse switching over, accepting a few seconds of possible data loss in a regional disaster.
A leader and two followers
Writes go to the leader's log. Each follower copies the log after its own delay. The program shows what each copy contains at a moment in time, which reads would be stale, and what a failover would lose. Then try the challenges: synchronous writes, choosing the new leader, quorums, Kafka acks and fencing tokens.
writes = [(0, "O1"), (2, "O2"), (4, "O3"), (6, "O4")] # (time, order)
lag = {"F1": 1, "F2": 4} # seconds behind the leader
now = 7
leader = [o for t, o in writes if t <= now]
followers = {f: [o for t, o in writes if t + d <= now] for f, d in lag.items()}
print("leader:", leader)
for f, data in followers.items():
stale = len(leader) - len(data)
print(f"{f}: {data} ({stale} behind)")
# The leader crashes now: promote the follower with the most data
new_leader = max(followers, key=lambda f: len(followers[f]))
lost = [o for o in leader if o not in followers[new_leader]]
print("promote", new_leader, "| acknowledged but lost:", lost)lag = {"F1": 1, "F2": 4} # seconds behind the leaderAsynchronous followers apply changes a little later. Each has its own lag.followers = {f: [o for t, o in writes if t + d <= now] for f, d in lag.items()}A follower has a write only if the write's time plus its lag has passed.new_leader = max(followers, key=lambda f: len(followers[f]))On failover, the most up-to-date follower is promoted, losing as little as possible.
Run it on your PC: async vs semi-sync replication
This program simulates a leader and two followers on a clock. A client writes every two ticks; followers copy after a delay. It reads from a lagging follower, crashes the leader, promotes the best follower and lists acknowledged writes that were lost. Then it repeats with semi-synchronous replication and checks quorum settings. Save it as replication_sim.py and run it.
Replication, failover and quorums
"""A leader with two followers, simulated step by step on a clock.
Writes go to the leader's log; followers copy the log after a delay (asynchronous replication).
We read from a follower, crash the leader, fail over, and count what was lost.
Then we repeat with synchronous replication to one follower (semi-sync)."""
def run(mode, lag={"F1": 2, "F2": 5}, crash_at=12):
leader_log = []
follower_log = {"F1": [], "F2": []}
pending = [] # (arrival_time, follower, entry)
acked = []
for t in range(0, crash_at):
if t % 2 == 0: # a client write every 2 ticks
entry = f"order@{t}"
leader_log.append(entry)
for f, d in lag.items():
pending.append((t + d, f, entry))
if mode == "semi-sync": # wait until F1 has it before saying OK
follower_log["F1"].append(entry)
pending = [p for p in pending if not (p[1] == "F1" and p[2] == entry)]
acked.append(entry)
for p in [p for p in pending if p[0] <= t]:
follower_log[p[1]].append(p[2])
pending.remove(p)
if mode == "async" and t == 7:
print(f" t={t}: read from F2 sees {len(follower_log['F2'])} of {len(leader_log)} orders (replication lag)")
# leader crashes; promote the follower with the longest log
new_leader = max(follower_log, key=lambda f: len(follower_log[f]))
lost = [e for e in acked if e not in follower_log[new_leader]]
print(f" leader crashed at t={crash_at}; promoted {new_leader} with {len(follower_log[new_leader])} of {len(acked)} acknowledged orders")
print(f" acknowledged but LOST: {lost if lost else 'none'}")
print("Asynchronous replication:")
run("async")
print("\nSemi-synchronous (leader waits for F1 before acknowledging):")
run("semi-sync")
# Quorum check for leaderless replication
print("\nQuorum reads/writes with N = 3 replicas:")
for w, r in [(1, 1), (2, 1), (2, 2), (3, 1)]:
print(f" W={w} R={r}: {'always reads the latest write' if r + w > 3 else 'may read stale data'}")
# In a terminal: python replication_sim.pyRecorded from a real run with Python 3.13; the simulation is deterministic, so you get the same output. Change lag or crash_at and see how many acknowledged writes are lost with async replication, and that semi-sync loses none as long as the follower it waited for survives.
Followers applying the log, one line at a time
The leader's log has three entries. Follower F2 already has the first one. Watch it apply only the entries it is missing, in order.
Worked examples: real problems, solved and traced in memory
Four replication problems, from counting copies to choosing quorum settings. Each runs live and is traced.
How much disk do copies need?
Problem statement
A Kafka cluster stores 20 TB of messages per week with replication factor 3, keeping 1 week. HDFS stores 50 TB with replication 3. How much raw disk does each need?
Kafka 20 TB × 3, HDFS 50 TB × 3
Kafka: 20 TB of data x 3 copies = 60 TB of disk HDFS: 50 TB of data x 3 copies = 150 TB of disk Total raw disk: 210 TB
Approach
- Raw disk = data × replication factor.
- Add both systems for the total.
Solution: run it live
What happens in memory, step by step
Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.
Which replicas are safe to read from?
Problem statement
Each read replica reports its lag in seconds. Reports can tolerate 30 s of lag; the checkout page tolerates 1 s. Print which replicas each workload may use.
r1: 0.4 s, r2: 12 s, r3: 75 s
checkout: ['r1'] reports : ['r1', 'r2']
Approach
- Store each replica's lag.
- For each workload, keep replicas with lag below its limit.
- If none qualifies, fall back to the primary.
Solution: run it live
What happens in memory, step by step
Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.
How much data can async replication lose?
Problem statement
Orders arrive at 3,000 per second. The async replica usually lags 0.5 s, but up to 4 s during peaks. How many orders could be lost if the primary died at a normal moment, and at a peak?
3,000 orders/s, lag 0.5 s normal, 4 s peak
normal: up to 1500 acknowledged orders could be lost peak : up to 12000 acknowledged orders could be lost RPO target: 0 orders -> needs synchronous or semi-sync replication
Approach
- Orders at risk = arrival rate × lag.
- Compute for both lags.
- Compare with the business's acceptable loss (RPO).
Solution: run it live
What happens in memory, step by step
Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.
Choose quorum settings for each workload
Problem statement
With N = 3 replicas, list all (W, R) combinations, mark which are consistent (R + W > N), and pick the fastest consistent setting for a write-heavy workload (smallest W) and for a read-heavy one (smallest R).
N = 3
consistent settings: [(1, 3), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] write-heavy pick (W, R): (1, 3) read-heavy pick (W, R): (3, 1)
Approach
- Enumerate W and R from 1 to N.
- Keep combinations with R + W > N.
- Write-heavy: smallest W, then smallest R. Read-heavy: smallest R, then smallest W.
Solution: run it live
What happens in memory, step by step
Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.
Check yourself
Quick revision
Lesson 3.3 in one screen
- Replication = copies on several nodes → availability, durability, read scaling, lower latency.
- Architectures: single-leader (most common), multi-leader (multi-region), leaderless (quorums, R + W > N).
- Sync (safe, slower) vs async (fast, can lose last writes) vs semi-sync (wait for one).
- Replication lag → stale reads; fix with read-your-writes routing.
- Failover: detect, promote most up-to-date follower, redirect, old leader rejoins as follower. RPO = data loss, RTO = downtime.
- Kafka: RF 3,
min.insync.replicas=2,acks=all, no unclean leader election. - Split brain prevented by majority quorums, fencing tokens/epochs and consensus (Raft, ZooKeeper). Replication ≠ backup.
Interview and viva questions
What is replication? Explain its types.
Replication keeps copies of the same data on multiple nodes for fault tolerance, availability, durability and read scalability. In single-leader replication one node accepts writes and streams changes to followers (PostgreSQL, MySQL, Kafka partitions). In multi-leader replication several nodes accept writes and exchange changes, useful across regions but requiring conflict resolution. In leaderless replication clients write to and read from several replicas and use quorums (R + W > N) for consistency, as in Cassandra and DynamoDB-style systems.
Compare synchronous and asynchronous replication.
In synchronous replication the leader acknowledges a write only after replicas confirm it, so no acknowledged data is lost if the leader fails, but write latency is higher and a slow or unavailable replica can block writes. In asynchronous replication the leader acknowledges immediately and replicas apply changes later, giving low latency but replication lag and possible loss of recent writes on failover. Semi-synchronous replication waits for at least one replica, balancing the two.
What is replication lag and what problems does it cause?
Replication lag is the delay between a write on the leader and its application on a follower. It causes stale reads, users not seeing their own updates (read-your-writes violations), data appearing to go backwards when reads hit different replicas (monotonic-read violations), and data loss on failover with asynchronous replication.
What is split brain and how is it prevented?
Split brain occurs when a network partition leads two nodes to act as leader simultaneously, both accepting writes so the data diverges. It is prevented by requiring a majority quorum to elect and keep a leader, by fencing tokens or epoch numbers that make storage reject writes from an old leader, and by using consensus algorithms such as Raft or Paxos (as in etcd, ZooKeeper and Kafka KRaft).
How does Kafka replication work?
Each partition has one leader broker and follower brokers that copy its log; followers that are fully caught up form the in-sync replica set (ISR). Producers choose acks=0 (no confirmation), acks=1 (leader only) or acks=all (all in-sync replicas). With replication factor 3, min.insync.replicas=2 and acks=all, an acknowledged message is stored on at least two brokers, and if the leader fails an in-sync follower takes over without losing it.
Practice problems
Replication exercises, from lag to quorums. The last two are business tasks.
Raw storage
Print the raw storage for 12 TB of data with replication factor 3.
12 TB, RF 3
36 TB
Show solution and explanation
print(12 * 3, "TB")How it works: Each copy needs the full space.
Replica lag
The leader is at log position 10,500 and a follower at 10,320. Print the lag in entries.
10500, 10320
180 entries behind
Show solution and explanation
print(10500 - 10320, "entries behind")How it works: Lag can be measured in log positions as well as seconds.
Majority size
Print the majority (quorum) size for clusters of 3, 4, 5 and 7 nodes.
3, 4, 5, 7
3 nodes -> majority 2 4 nodes -> majority 3 5 nodes -> majority 3 7 nodes -> majority 4
Show solution and explanation
for n in [3, 4, 5, 7]:
print(n, "nodes -> majority", n // 2 + 1)How it works: A 4-node cluster needs 3 for a majority, so it tolerates only 1 failure, like a 3-node cluster.
Failures tolerated
Print how many node failures a majority-quorum cluster tolerates for 3, 5 and 7 nodes.
3, 5, 7
3 nodes tolerate 1 failures 5 nodes tolerate 2 failures 7 nodes tolerate 3 failures
Show solution and explanation
for n in [3, 5, 7]:
print(n, "nodes tolerate", (n - 1) // 2, "failures")How it works: A cluster keeps working while a majority is alive.
Promote the best follower
Given each follower's last log position, print the one to promote.
F1: 880, F2: 905, F3: 870
F2
Show solution and explanation
pos = {"F1": 880, "F2": 905, "F3": 870}
print(max(pos, key=pos.get))How it works: The most up-to-date follower loses the least data.
Writes at risk
Orders arrive at 1,200/s. Async lag samples are given. Print the maximum number of orders at risk.
lags [0.2, 0.4, 1.8, 0.3]
2160 orders at risk in the worst case
Show solution and explanation
lags = [0.2, 0.4, 1.8, 0.3]
print(int(1200 * max(lags)), "orders at risk in the worst case")How it works: Plan for the worst lag, not the average.
Stale-read probability
A read goes to one of 3 replicas at random; at that moment 1 replica has the latest write. With R reads combined (taking the newest value), what is the chance of a stale result for R = 1, 2, 3?
3 replicas, 1 up to date
R=1: chance of stale result 67% R=2: chance of stale result 33% R=3: chance of stale result 0%
Show solution and explanation
from math import comb
N, fresh = 3, 1
for R in [1, 2, 3]:
stale = comb(N - fresh, R) / comb(N, R)
print(f"R={R}: chance of stale result {stale:.0%}")How it works: Reading more replicas lowers the chance of missing the newest value; with R + W > N it becomes zero.
Cost of a standby
A database server costs Rs 2.5 lakh a month. A synchronous standby doubles that. One hour of downtime costs the business Rs 40 lakh, and without a standby a failure causes 4 hours of downtime about once a year. Is the standby worth it?
Rs 2.5 lakh/month, Rs 40 lakh/hour, 4 h/year
standby: Rs 30.0 lakh/year vs expected downtime: Rs 160 lakh/year worth it
Show solution and explanation
standby_per_year = 2.5 * 12
downtime_cost = 40 * 4
print(f"standby: Rs {standby_per_year} lakh/year vs expected downtime: Rs {downtime_cost} lakh/year")
print("worth it" if downtime_cost > standby_per_year else "not worth it")How it works: Availability decisions are business decisions: compare the cost of copies with the cost of being down.
Cross-region RPO
A bank replicates asynchronously to a DR region with an average lag of 2 s and 800 transactions/s. The regulator expects RPO under 5 minutes. Print the transactions at risk and whether the RPO is met.
2 s lag, 800/s, RPO 300 s
transactions at risk: 1600 RPO met
Show solution and explanation
lag, rate, rpo = 2, 800, 300
print("transactions at risk:", lag * rate)
print("RPO met" if lag <= rpo else "RPO NOT met")How it works: Async cross-region replication usually meets minute-level RPOs, while synchronous replication across distant regions would slow every transaction.
Real-world scenario questions (asked in company interviews)
Replication questions from real incidents and interviews. Decide your answer first, then open the model answer.
Make the orders database survive a server failure
The orders database runs on one server. Management wants it to survive a hardware failure with at most a minute of downtime and no lost orders.
The interviewer is checking: can you design basic replication with clear RPO/RTO?
Show a strong answer
- Add a synchronous (or semi-synchronous) standby in another availability zone: RPO ≈ 0 for committed orders.
- Automate failover with health checks and a managed service or a tool like Patroni, aiming for an RTO under a minute.
- Connect apps through a stable endpoint (DNS or proxy) that moves to the new primary.
- Add async read replicas for reports.
- Keep point-in-time backups for mistakes and test restores regularly.
Avoid: saying “take nightly backups” as the answer to availability.
“I paid but the app says unpaid”
After adding read replicas, some customers see “payment pending” for a few seconds right after paying, and pay again.
The interviewer is checking: do you recognise replication lag and read-your-writes?
Show a strong answer
Reads go to asynchronous replicas that haven’t applied the payment yet. Fix: route a user’s reads to the primary for a short window after they write (or for critical screens like payment status), or read from a replica only if it has caught up to the user’s last write position. Make the payment API idempotent so a second tap doesn’t charge twice, and show “processing” instead of “unpaid” while confirming.
Avoid: removing replicas entirely, or adding a fixed sleep before reading.
Messages lost during a broker restart
During a rolling restart of Kafka brokers, a few order events disappeared, although producers logged success.
The interviewer is checking: do you know how acks, ISR and unclean leader election interact?
Show a strong answer
Producers were probably using acks=1 (or the topic allowed unclean leader election), so a leader acknowledged messages and then lost leadership before followers copied them. Fix: replication factor 3, min.insync.replicas=2, producers with acks=all and idempotence enabled, and unclean.leader.election.enable=false. Restart brokers one at a time, waiting for under-replicated partitions to return to zero.
Avoid: adding retries in consumers, which can’t bring back a message that was never stored.
“Is replication the same as backup?”
Interviewers like this question because many candidates say yes.
The interviewer is checking: do you understand what each protects against?
Show a strong answer
No. Replication keeps live copies so the system survives machine, disk or zone failures with little downtime; every change, including mistakes and corruption, is copied within seconds. Backups are point-in-time copies kept separately so you can restore data after accidental deletes, bugs, ransomware or logical corruption. Production systems need both, and backups must be tested by actually restoring them.
Avoid: saying “we have three replicas, so we don’t need backups”.