No shared memory, no shared clock, and a network that lies
A fan on a train taps Hold seat. The spinner turns for 5 s, then "Something went wrong". She taps again. Did the first tap hold a seat? Will she hold two? Be charged twice?
"A distributed system is one in which the failure of a computer you didn't even know existed can render your own computer unusable." — Leslie Lamport
At scale failure is the norm: 1 − (1 − p)N. With p = 0.1% per machine per day, 3,000 machines see a failure on ~95% of days.
inventory
SeatHeld
payment
/health
The failures that hurt are not clean crashes: they are slow, partial and gray.
Deutsch et al., Sun Microsystems (1994; Gosling added the 8th in 1997). Each one returns in a later class.
inventory → payment: authorise R$ 450 … silence … timeout after 2 s.
inventory → payment: authorise R$ 450
Timeouts are a trade-off (too long: threads pile up; too short: false alarms and extra load). Retries must be safe → idempotency.
Effectively once = at-least-once delivery + idempotent processing.
"Exactly-once delivery" without qualification is a red flag in an interview.
GET
PUT
DELETE
POST
x = x + 1
UPDATE seats SET status = 'HELD', fan_id = 42, hold_key = :key WHERE id = 'A-12' AND (status = 'FREE' OR hold_key = :key);
When to say OK: async (fast, may lose writes on failover) · sync (slowest follower decides) · semi-sync / quorum (the usual compromise).
The fan pays at 10:00:41, opens My tickets 300 ms later — served by an async replica. The list is empty.
Fix it precisely: read-your-writes, not global strong consistency.
P is not optional — "CA" is not a choice for replicated data. And CAP's C is linearizability, not ACID's C.
Partition → A or C; Else → Latency or Consistency.
Hence: synchronous across zones (EC), asynchronous or home-region partitioning across regions (EL). Illustrative orders of magnitude.
UPDATE
Multi-region: each event has a home region (the venue's) — strong consistency stays local, a partition only affects cross-region holds.
Use 3 or 5 nodes, spread so that no zone holds a majority. Two nodes at 99% each = 98.01%.
term + 1
AppendEntries
etcd defaults: heartbeat 100 ms, election timeout 1,000 ms → a leader crash costs ~1–2 s of no writes. Used by etcd, Consul, CockroachDB, Kafka KRaft.
ONE
QUORUM
ALL
Overlap is necessary, not sufficient: sloppy quorums, concurrent writes and LWW still produce anomalies. Tunable consistency ≠ consensus.
UPDATE scheduled_jobs SET last_run_at = now(), fencing_token = :token WHERE job_id = 'onsale-reminder-42' AND fencing_token <= :token;
BoxOffice: Patroni + 3-node etcd elects the PostgreSQL primary; the old primary demotes itself. Use consensus, don't build it.
Coordinator crashes after the votes → participants are in doubt, seat A-12 stays locked. Availabilities multiply (all up at once), two round trips + fsyncs, and the payment provider cannot join.
2PC lives on inside distributed databases with a replicated coordinator (Spanner, CockroachDB, Kafka transactions) — not across microservices.
PENDING
CANCELLED
RESERVED_FOR_PAYMENT
SOLD
CONFIRMED
order
currentTimeMillis
nanoTime
Last-write-wins with a node 50 ms fast: a release at .040 stamped .090 beats a hold at .060 → Carla paid and has no seat. The fastest clock wins every conflict.
sql
nosql
cache
cdn
dns
thirdparty
queue
stream
kafka
scheduler
Every component in the playground inherits one of these problems — ask which one before adding it to a design.
R + W > N
Outline: (1) why distribute and failure models; (2) the unreliable network, timeouts and idempotency; (3) replication and consistency models; (4) CAP and PACELC; (5) consensus and quorums; (6) time and clocks.