Concept · Consistency & coordination

Clocks and ordering

Why wall clocks can’t order events across machines, and what Lamport and vector clocks do instead.

3 minLamport clockvector clockclock skewNTP

Ordering events is easy on one machine and surprisingly hard across many, because each machine has its own clock.

Two kinds of clock

  • Wall-clock time (a date and time) is synchronised by NTP, typically to within a few milliseconds of other machines — but it drifts, and NTP can step it forwards or backwards. Leap seconds and misconfigured hosts make it worse.
  • Monotonic time only moves forward and measures elapsed time on one machine. It's meaningless across machines.

Use monotonic time for durations and timeouts (Go's time.Since does). Never order events from different machines by wall-clock timestamp alone: a write on a machine whose clock runs 20 ms fast can appear "newer" than a later write elsewhere, and last-write-wins will keep the wrong one.

Lamport clocks

A Lamport clock is a counter per node:

text
on each local event:     counter += 1
on sending a message:    counter += 1; attach counter
on receiving (c_msg):    counter = max(counter, c_msg) + 1

If event A could have caused event B, A's timestamp is smaller. Breaking ties by node ID gives every event a total order all nodes agree on. Lamport clocks can't tell you whether two events were concurrent.

Vector clocks

Each node keeps a counter per node. Comparing two vectors tells you whether one event happened before the other or whether they were concurrent — which is how some databases detect conflicting writes that need merging. The cost is a vector that grows with the number of writers.

Hybrid and bounded clocks

  • Hybrid logical clocks (CockroachDB, MongoDB) combine physical time with a logical counter: close to wall time, but respecting causality.
  • Bounded uncertainty: Google Spanner's TrueTime uses GPS and atomic clocks to know the maximum clock error, and waits out that uncertainty before committing, which gives globally consistent timestamps.

In practice

When order matters, let one place assign it: a single leader, a per-partition sequence number (as in chat), or a log. See unique ID generation and consistency models.

Learn it in depth