SD System Design In Depth
0%
lesson system-designlogical-clockscausality

Clocks and ordering

Module 3.2: Distributed Coordination, Consensus & Leases Updated Sep 17, 2026
📄 Cheat Sheet
Distributed Systems 4.1: Logical time
Martin Kleppmann Distributed Systems 4.1: Logical time Watch on YouTube ↗

Kleppmann's lecture on Lamport and vector clocks is the clearest treatment of the one-way implication and concurrency detection the lesson emphasises.

0:00 / --:--

Concrete scenario

Node A sends a message to Node B, but B has an earlier wall-clock reading when it acts on the message.

Mechanics

Wall clocks represent calendar time and may be stepped or slewed by synchronization; monotonic clocks are local tools for elapsed durations but are not comparable across machines. Lamport clocks guarantee that causally prior events receive lower timestamps, but the reverse implication is false. Vector clocks can distinguish causal order from concurrency at metadata cost.

Failure mode

Last-write-wins using unsynchronized wall time can discard a causally later update. A timeout measured on a wall clock can be distorted by a clock adjustment, and vector metadata can grow with participants.

Trade-off

Physical time is useful for user timestamps and retention; logical time is useful for ordering. Hybrid logical clocks combine both but still require defined uncertainty, tie-breaking, and application conflict semantics.

Worked example: Lamport versus vector clocks

Three nodes, A, B and C, each start with a counter of 0.

  • A performs a local event: Lamport A = 1. Vector A = [1,0,0].
  • A sends m1 to B: A = 2, and m1 carries 2 (vector [2,0,0]).
  • C performs a local event independently: C = 1, vector [0,0,1].
  • B receives m1: B = max(0,2)+1 = 3. Vector B = [2,1,0].
  • C sends m2 to B carrying 2 (vector [0,0,2]). B receives: B = max(3,2)+1 = 4. Vector B = [2,2,2].

Compare A's send event (Lamport 2, vector [2,0,0]) with C's first event (Lamport 1, vector [0,0,1]). Lamport suggests C's event came first, but the vectors are incomparable (neither is less than or equal to the other in every component), so the events are really concurrent. Only vector clocks reveal that.

Clock types

ClockAnswersSizeDetects concurrencyUsed by
Wall clock (NTP)Calendar time, plus or minus a few ms (worse under load or skew)8 bytesNoLogs, TTLs, user-facing timestamps
MonotonicElapsed time on one host8 bytesNot applicableTimeouts, latency metrics
LamportA total order consistent with causalityOne integerNoLog ordering, Raft terms (similar idea)
Vector / version vectorExact causalityO(nodes)YesRiak, Dynamo, CRDT libraries
Hybrid logical clock (HLC)Causality plus closeness to physical timePhysical time plus a counterNoCockroachDB, YugabyteDB, MongoDB cluster time
TrueTimeA bounded interval [earliest, latest]Two timestampsNo, but supports external consistencyGoogle Spanner, which waits out the uncertainty, typically under 7 ms

How real systems order events

  • Spanner uses GPS and atomic clocks to keep uncertainty small, and "commit-waits" until the timestamp is guaranteed to be in the past everywhere.
  • CockroachDB uses HLC with a maximum offset (default 500 ms). A read that finds a value inside its uncertainty window restarts at a higher timestamp.
  • Snowflake IDs (Twitter) combine milliseconds, a machine ID and a sequence number. They are roughly time-sortable, but they do not capture causality across machines.
Check yourself Question 1 of 3
Measuring timeouts recall
From: Mechanics

A service measures request latency by subtracting two wall-clock readings. Occasionally it reports negative latency or fires a timeout instantly. What should it use instead?

Vector Clocks vs Lamport Clocks

Each event gets a Lamport timestamp L and a vector clock [A, B, C]. Lamport order is consistent with causality, but only vector clocks can tell you two events are concurrent.

Process A
Process B
Process C
Create a few events, then pick two to compare.

Key Takeaways

Use monotonic clocks for local durations and wall clocks for calendar time.
Lamport order preserves causality in one direction but cannot detect concurrency.
Vector and hybrid clocks add metadata in exchange for stronger ordering information.
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue