Raft solved the consensus problem for one shape of replication: single-leader. But there are three canonical shapes — and most production systems use whichever one matches their workload best. Time to map the whole landscape.
Every distributed system replicates data. There's no way around it — a single copy of anything is a single point of failure, and storing only one copy makes the system unavailable the instant that machine hiccups. Replication isn't optional. But the moment you have multiple copies, you've signed up for a new set of problems: keeping them in sync, deciding where reads come from, handling the cases where they disagree. Raft (M.24) solved one specific version of this. Now we widen the lens.
N copies means tolerating N-1 losses. This is the simplest reason and the foundation everything else builds on.The cost of all this is the same one we've been circling for the whole phase: multiple copies means multiple sources of truth, and they can disagree. CAP (M.21) tells you that disagreement is inevitable during partitions. Consistency models (M.22) tell you how disagreement is allowed to manifest. Lamport clocks (M.23) tell you how to track causality across copies. Consensus (M.24) tells you how copies can agree on a total order. This module is where the four come together — it surveys the actual shapes of replication that real systems deploy and shows you how to pick.
Every replication scheme in production fits one of three patterns (or some hybrid of them). Each makes different decisions about where writes go — which is the question that drives every other property. Below: the patterns, their canonical diagrams, the systems that use them, and the trade-off each makes explicit.
The classic pattern from M.24. A single node is the authoritative writer; all client writes route there. The leader replicates each change to followers (synchronously, asynchronously, or semi-sync). Reads can come from any replica — though leader-only reads guarantee linearizability while replica reads are eventually consistent.
Each region has its own leader that accepts writes. Leaders replicate changes to each other asynchronously. Geographic write locality is the killer feature — a user in Tokyo writes to Tokyo's leader at low latency, then changes propagate to US and EU asynchronously. The cost: conflicts when the same key gets written in two regions before they've synced.
Every node is equal. Clients (or a coordinator) write to W nodes in parallel and read from R nodes. If W + R > N, every read overlaps at least one node that has the latest write — strong consistency through math, not coordination. Background "anti-entropy" keeps replicas in sync over time.
Notice the pattern: each step "weaker" trades correctness machinery for operational flexibility. Single-leader is the easiest to reason about — one source of truth — but the leader is a bottleneck and a SPOF for writes. Multi-leader breaks the bottleneck and gives geographic locality at the cost of conflict resolution. Leaderless removes the leader entirely, gaining extreme availability and per-call consistency control at the cost of more complex client logic.
None of these is "best." Each fits some workload extremely well and others badly. Postgres with single-leader replication is the right choice for 99% of business applications. Cassandra is the right choice for high-write, write-spreadable workloads at scale. Multi-leader fits global active-active deployments where the latency win justifies the conflict cost. The skill is matching pattern to problem.
Within any replication pattern, there's a second knob: how many replicas must acknowledge before the client gets "OK"? This is the synchronicity dial. The three positions trade durability for latency, and you'll see each in production. The default in your favorite database is probably one of them — and you'd be surprised which one.
Leader writes locally, then waits for every follower to confirm. Strongest durability — if the leader dies right after acking, every follower has the data. Slowest writes — bound by the slowest follower's RTT. A single stuck replica blocks everything.
Leader waits for quorum acknowledgements (in Raft: majority; in Dynamo-style: W nodes). The pragmatic default for most production systems. Lose the leader and at least one other has it. Faster than full sync because slow tail replicas don't block.
Leader writes locally and responds to client immediately. Replication happens in the background. Fastest writes — pure local I/O. Risk: if the leader dies before background replication completes, data is permanently lost. Many production MySQL/Postgres deployments default to this.
The choice cascades into your CAP/PACELC trade-off from M.21. Synchronous replication = strong consistency, slow writes, low availability under partition (any unreachable replica blocks). Asynchronous = eventual consistency, fast writes, high availability — but a window of potential data loss if the leader dies during replication lag. Semi-synchronous is the engineering compromise: most of the durability, most of the latency benefit, partition tolerance because slow tails don't block.
One footgun worth flagging: many systems default to async replication and don't make it loud. MySQL's default replication is async — if your primary dies before its binlog replicates, that data is gone. PostgreSQL's synchronous_commit setting controls this and is often overridden to async for performance. Redis replication is async by default. If durability matters for your data (and it usually does), check the setting explicitly and pick semi-sync at minimum.
Below: pick a replication pattern. Pick a scenario. Watch the topology animate, read what happens, see the verdict. Switch patterns to see how each handles the same scenario differently. Three patterns × three scenarios = nine outcomes you can compare side by side.
Single-leader avoids conflicts by design — there's only one writer. The moment you have multi-leader or leaderless, conflicts become inevitable: two clients write to the same key on different nodes before replication catches up, and now you have two versions of the truth. The system must decide what to do. Four strategies are common in practice; each makes different trade-offs.
Simplest: each write gets a wall-clock timestamp; the later one always wins on read. Dangerous: it silently discards data. If two clients write concurrently with skewed clocks, one write disappears with no signal. Cassandra defaults to this. Effective when conflicts are rare and approximate truth is acceptable; catastrophic for billing, inventory, or anything ledger-shaped.
From M.23. Each write carries a vector clock; on read, the system detects concurrent versions (incomparable vectors) and returns both as siblings. The application chooses how to merge: pick one, union, custom logic. The Riak / original-Dynamo model. Honest but pushes work onto the application; you have to actually handle siblings or they accumulate.
A small toolkit of data types (counters, sets, registers, sequences) where the merge operation is commutative, associative, and idempotent — applying writes in any order produces the same final state. Adding "5" to a counter and adding "3" gives 8 regardless of which arrives first. Used in Redis Enterprise, Riak, real-time collaboration (Figma, Google Docs). Beautiful when applicable; limited expressiveness.
The system flags conflicting versions; the application reads, merges per domain rules, writes back. Examples: a shopping cart unions items from both versions; a profile update uses the most recent change per field. Maximum flexibility, maximum complexity. The reality for most non-trivial multi-leader and leaderless deployments — you'll eventually need this.
The order above is roughly strength of guarantee: LWW is the weakest (loses data), CRDTs are the strongest (mathematically guaranteed convergence), with vector clocks and app-merge in between. The order is also roughly cost of implementation: LWW is one line of code, CRDTs require designing your data model around the constraints. Real systems often layer them: CRDTs for counters and sets, app-merge for complex domain objects, vector clocks underneath both for detection.
And the question worth asking before all of this: can you avoid conflicts entirely by routing writes by key? If a user's profile is always written from their nearest region, you'll never have two regions concurrently writing the same profile. Many "multi-leader" deployments are actually partitioned single-leader under the hood — each shard has one leader, but the leaders are spread across regions. This sidesteps conflict resolution while keeping write locality. It's the cleanest design when your workload allows it.
Every term you'll find in the docs of a replicated system and every architecture review involving distributed data.
N. Higher = more durable + available, more storage and write amplification. Typical: 3 in same region, 6 across regions.N = total replicas, W = nodes required to ack a write, R = nodes consulted for a read. When W + R > N, you get strong consistency.Test the replication intuition. Click an answer; explanation drops in instantly.
Perfect. The three patterns and their trade-offs are yours — and so is Phase E. Next phase: events.
The replication landscape. These ideas show up in every distributed database conversation and architecture review.
Single-leader: simple, bottlenecked. Multi-leader: geo-local, conflict-prone. Leaderless: highly available, complex. Pick by workload, not by aesthetics.
Most systems default to async replication. That includes a window of data loss on leader failure. Check the setting. Pick semi-sync at minimum for anything that matters.
The moment you have multi-leader or leaderless writes, conflicts will happen. LWW, vector clocks, CRDTs, or app-merge — pick consciously, before production teaches you.