SD System Design In Depth
0%
lesson system-designdistributed-systemsfailure

Distributed systems foundations

Module 3.2: Distributed Coordination, Consensus & Leases Updated Sep 17, 2026
📄 Cheat Sheet
Distributed Systems 2.3: System models
Martin Kleppmann Distributed Systems 2.3: System models Watch on YouTube ↗

Kleppmann's Cambridge lecture on system models covers exactly this lesson: reliable versus fair-loss links, crash-stop, crash-recovery and Byzantine nodes, and synchronous, partially synchronous and asynchronous timing.

0:00 / --:--

The Reality of Distributed Physics: Why Networks Fail

A distributed system is a collection of autonomous computing nodes that communicate over a network, coordinating actions by passing messages. In single-machine systems, memory reads and function calls are deterministic, microsecond operations. In distributed systems, computing across physical space introduces the 8 Fallacies of Distributed Computing (the first seven listed by Peter Deutsch at Sun in 1994; the eighth, "the network is homogeneous", added by James Gosling around 1997):

  • The network is reliable.
  • Latency is zero.
  • Bandwidth is infinite.
  • The network is secure.
  • Topology doesn't change.
  • There is one administrator.
  • Transport cost is zero.
  • The network is homogeneous.

Failure Models in Distributed Infrastructure

flowchart TD NodeA["Node A (Sender)"] -->|"1. Network Packet (SYN/DATA)"| Net{"Physical Network Layer: Routers / Fiber"} Net -->|"Asymmetric Partition / Packet Drop"| BlackHole[("Black Hole / Delay")] Net -->|"Delivered After 5,000ms"| NodeB["Node B (Receiver)"] NodeA -->|"Timeout Reached"| Question{"What Happened to the Request?"} Question --> F1["Case 1: Request crashed before processing"] Question --> F2["Case 2: Request processed, but ACK dropped on return"] Question --> F3["Case 3: Node B is paused in Garbage Collection (STW)"]

The Three Distributed Failure Modes

1. Crash-Stop (Fail-Stop)

A node halts operations abruptly (e.g., kernel panic, power loss, OOM kill). Once stopped, it never transmits another packet. This is the simplest failure model to design for, as dead nodes remain silent.

2. Crash-Recovery

A node crashes, restarts after several seconds or minutes, reads its persistent write-ahead log (WAL) from disk, and rejoins the cluster with state that lags behind the current state. Algorithms must handle stale reads and catch-up log streams.

3. Byzantine Faults (Arbitrary / Malicious)

Nodes transmit corrupted messages, lie about state, or act maliciously. Solved via Byzantine Fault Tolerant (BFT) consensus (e.g., PBFT, Tendermint, HotStuff; Proof-of-Stake chains pair stake-based Sybil resistance with protocols like these). In private datacenter environments, engineers assume non-Byzantine failure models (Crash-Recovery) to avoid BFT's O(N2) message complexity.

Worked example: why a timeout cannot tell you what happened

Service A calls B to charge a card, with a 1-second timeout. Measured p99 latency is 300 ms, but during GC pauses B sometimes takes 4 seconds. A times out and retries.

  • Case 1: the request was lost. Retrying is correct.
  • Case 2: B charged the card and the response was lost. Retrying double-charges.
  • Case 3: B is mid-GC and will process both the original and the retry.

The only safe design is an idempotency key. A sends charge_id=abc, and B stores it with the result in the same transaction, so the retry returns the stored result.

Timing models

ModelAssumptionWhat is possibleReality check
SynchronousKnown upper bounds on message delay and processing timePerfect failure detection by timeoutNot true of real networks or GC runtimes
Partially synchronousBounds hold eventually, after some unknown timeConsensus (Raft, Paxos) with safety always and liveness once stableThe practical model for datacentres
AsynchronousNo timing bounds at allNo deterministic consensus (FLP, 1985)A useful worst case for proving safety

Node failure models

ModelBehaviourTypical defence
Crash-stopHalts and never returnsReplication plus failover
Crash-recoveryHalts, restarts, may lose in-memory stateDurable logs (fsync), rejoin and catch up
OmissionDrops some messagesRetries with idempotency
ByzantineArbitrary or malicious behaviourBFT protocols with 3f+1 nodes to tolerate f faults, plus signatures

Real-world evidence

  • Bailis and Kingsbury's survey "The Network is Reliable" documents real partitions at Google, Microsoft, Amazon and others, including partial and asymmetric ones.
  • Jepsen tests have repeatedly found data loss in databases whose designs assumed clocks or networks behave well.
  • Google's Chubby and Spanner papers both treat long process pauses and clock uncertainty as normal operating conditions.

Design checklist

  • Every remote call has a timeout, and every retried operation is idempotent.
  • Every piece of state has exactly one owner, or an explicit conflict-resolution rule.
  • Failure detection is treated as a suspicion, never a certainty. Anything that acts on a suspicion, such as failover, must fence the old owner.
Check yourself Question 1 of 3
Datacenter failure model recall
From: The Three Distributed Failure Modes

Inside a single organisation's datacenters, which failure model do coordination systems usually design for, and why not Byzantine?

Key Takeaways

Networks are inherently asynchronous and unreliable; timeouts do not distinguish between server death and dropped return packets.
Distributed systems design for Crash-Recovery models where nodes restart and rejoin with stale logs.
Byzantine fault tolerance is reserved for untrusted peer networks (blockchain); internal systems use crash-fault-tolerant Paxos/Raft, usually inside coordination services and databases (etcd, ZooKeeper, Consul, Spanner) rather than in each microservice.
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue