Unit 5 · Distributed & cloud · Lesson 4 of 14
Clocks, ordering, leases and fencing
Step 1: Learn the ideas
- Time-of-day versus monotonic clocks; synchronization drift and steps
- Happened-before and Lamport timestamps
- Vector clocks and version vectors
- Total order broadcast and its link to consensus
- Leases and the bounded-drift assumption
- Process pauses and why expiry alone is unsafe
- Epochs, terms and fencing tokens
- Coordination services: sessions, ephemeral nodes, watches, revisions
- Leader election with a coordination service
- Bounded clock uncertainty and commit wait (awareness)
Why it matters
"Use the timestamp to decide which write wins" and "take a lock with a 30-second TTL" sound reasonable and lose data. Clocks on different machines disagree and can jump backwards, and a process can stop for seconds without noticing. Interviewers probe this to see whether you know which orderings are trustworthy and how to keep an exclusive role safe when its holder may be slow rather than dead.
Core ideas
Physical clocks. Time-of-day clocks are synchronized over the network and can step forwards or backwards; monotonic clocks only move forward and are right for measuring durations on one machine, but mean nothing across machines. Skew between nodes is usually small but has no hard bound in bad cases, so wall-clock last-writer-wins can silently drop the later write.
Logical clocks. Lamport defined happened-before: a precedes b if they occur in that order in one process, if a is a send and b the matching receive, or by transitivity. A Lamport clock is a counter incremented at each event and set to max(local, received) + 1 on receipt. If a happened before b, then L(a) < L(b); the converse fails, so Lamport timestamps cannot reveal whether two events were concurrent. Breaking ties by node ID yields a total order consistent with causality, enough for a fair mutual-exclusion queue but not for detecting conflicts.
A vector clock keeps one counter per node. Event a precedes b exactly when a's vector is less than or equal to b's in every component and differs in at least one; if neither dominates, the events are concurrent. Version vectors apply this to replicas of a key, so concurrent updates are kept as siblings instead of one overwriting the other.
Leases. A lease is a lock that expires. The holder may act only while sure the lease is valid, so it measures the lease from before it sent the request and stops early by a margin covering clock-rate drift. Leases cut coordination traffic (a leader can serve reads locally while its lease holds), but their safety rests on timing assumptions.
Pauses break leases; fencing repairs them. A holder can check its lease, pause for a long garbage collection, and then write after the lease expired and someone else acquired it. The fix is a fencing token: the lock service returns a number that increases with every grant, clients send it with each write, and the storage rejects any token lower than the highest it has seen. Raft terms and other epochs play the same role between leaders.
client A: acquire -> token 33 ... long pause ... write(token 33) -> rejected
client B: acquire after A's lease expired -> token 34 -> write(token 34) -> accepted
storage: remembers the highest token seen (34) and rejects anything lower
Coordination services. ZooKeeper and etcd run consensus internally and expose small, strongly ordered stores with sessions or leases, ephemeral keys that vanish when their owner's session ends, watches for change notification, and increasing versions or revisions that can serve as fencing tokens. Use them for leader election, membership, configuration and locks; keep bulk data elsewhere. Read their guarantees precisely: ZooKeeper may answer reads from a lagging server unless the client syncs first, while etcd reads are linearizable by default and can be relaxed to faster, possibly stale serializable reads.
Ordering needs consensus. Total order broadcast (every node delivers the same messages in the same order) is equivalent to consensus, which is why a globally ordered log needs a consensus-backed sequencer or a single leader per partition.
Common misconceptions
- "Timestamps from synchronized clocks order events correctly." Skew and steps can invert causally related writes; use logical clocks or a single sequencer when order matters.
- "A lock with a TTL guarantees mutual exclusion." Not if the holder can pause or its clock runs slow; the protected resource must check a fencing token or epoch.
- "Lamport clocks detect concurrent writes." They impose a total order but lose concurrency information; vector clocks or version vectors detect conflicts.
- "A lock in a cache store with expiry is fine." Fine for efficiency (avoiding duplicate work); correctness-critical exclusion needs a consensus-backed service plus fencing.
- "Leases need perfectly synchronized clocks." They need bounded drift rates and a margin, not identical clocks; the real dangers are pauses and unbounded drift.
How to approach it
Read DDIA Ch. 8 on clocks and fencing, then Lamport's paper and Kleppmann's locking article, which together cover most interview questions. Practice computing clocks on drawn message diagrams and build the lock in the 6.5840 key/value lab on top of conditional writes. Graduates should explain why wall clocks are unreliable. Mid-level candidates should design a lease with fencing. Senior candidates should state the timing assumptions of a whole design and know when to avoid distributed locks by giving each partition a single owner.
Suggested order
- 1Read DDIA Ch. 8, sections "Unreliable Clocks" and "Knowledge, Truth, and Lies", focusing on process pauses, leases and fencing tokens.
- 2Read Lamport's "Time, Clocks, and the Ordering of Events" through the logical-clock and total-ordering sections; compute clocks on a three-process diagram.
- 3Re-read DDIA Ch. 5, "Detecting Concurrent Writes", and Ch. 9, "Ordering Guarantees", for version vectors, Lamport timestamps and total order broadcast.
- 4Read Kleppmann's "How to do distributed locking" and write the fencing-token argument in your own words.
- 5Read the 6.5840 LEC 9 notes on ZooKeeper and the etcd API guarantees page; compare sessions and ephemeral znodes with etcd leases and revisions.
- 6Implement the lock in 6.5840 Lab 2 on top of versioned conditional puts, then sketch how fencing would protect a downstream store.
Step 2: Check off what you can do
Tap each one you can genuinely do or explain. Each earns 10 XP.
Step 3: Go deeper
Designing Data-Intensive ApplicationsStart here
O'Reilly Media (author's book site)Section: Ch. 8: The Trouble with Distributed Systems (clocks, pauses, fencing), with Ch. 9 on ordering
Unreliable clocks, process pauses, leases, fencing tokens and ordering guarantees.
Open(opens in a new tab)Link responded, 5 Oct 2026Time, Clocks, and the Ordering of Events in a Distributed SystemStart here
Leslie Lamport's publications pageOriginal definition of happened-before and logical clocks.
Open(opens in a new tab)Link responded, 5 Oct 2026How to do distributed locking
Martin Kleppmann's blogWhy expiring locks fail under pauses and how fencing tokens fix them.
Open(opens in a new tab)Link responded, 5 Oct 2026etcd documentation (v3.6): API guarantees and API model
etcd project (CNCF)Concrete guarantees of a Raft-backed coordination store: read consistency options, leases, revisions and watches.
Open(opens in a new tab)Link responded, 5 Oct 2026MIT 6.5840 Distributed Systems
MIT PDOSSection: LEC 9: ZooKeeper (lecture notes)
ZooKeeper sessions, ephemeral and sequential znodes, and building locks on them.
Open(opens in a new tab)Link responded, 5 Oct 2026
Step 4: Practice
Draw a message diagram with three processes and eight events, compute Lamport and vector clocks, and list every concurrent pair; repeat until it takes under five minutes. Build the lock in the 6.5840 key/value lab and ask what happens if a client pauses while holding it. Then write a one-page leader-election design on etcd or ZooKeeper that includes the fencing check performed by the storage layer, and walk it through a leader paused past its lease.
- MIT 6.5840 Lab 2: Key/value server with at-most-once Puts and a lockOpen(opens in a new tab)Not attemptedMIT 6.5840
- MIT 6.5840 labs: key/value server, Raft, fault-tolerant and sharded key/valueOpen(opens in a new tab)Not attemptedMIT 6.5840
Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).
Step 5: Test yourself
Answer each one out loud or on paper before you finish the lesson.
- Question 1Why must durations be measured with a monotonic clock?
- Question 2If L(a) < L(b), what can you conclude about a and b?
- Question 3How do version vectors let a key-value store keep both of two concurrent writes?
- Question 4What breaks if a lease holder's clock runs slower than the lock service's?
- Question 5Where must the fencing check happen, and why can the client not do it?
- Question 6When is a cache-backed lock acceptable, and when is it not?
You’re done when you can
- Compute Lamport and vector clocks for an unseen message diagram and identify all concurrent events without errors.
- Explain the fencing-token fix for a paused lock holder in under two minutes, without notes.
- Design a lease-based leader with an explicit drift margin and a fencing mechanism, and state its assumptions.
- Describe what an etcd lease or a ZooKeeper ephemeral node guarantees and what it does not.
Finish the lesson
Unlocks next: Distributed transactions and recovery research


