The full picture
🎬 Vector clocks: telling 'stale' apart from 'concurrent'
1 / 5Three processes, each holding a counter per process: [P1, P2, P3]. A process bumps its OWN entry on every local event, and ships the whole vector with every message.
| Lamport | Vector clock | |
|---|---|---|
| Size | one integer | one integer per node |
| A → B implies L(A) < L(B) | yes | yes |
| L(A) < L(B) implies A → B | no | yes (element-wise) |
| Detects concurrency | no | yes — neither vector dominates |
| Used for | total order, ticket numbers, term numbers | conflict detection, siblings, causal reads |
- Happens-before (→) is the actual concept these implement: A → B if they're on the same node in program order, or A is a send and B its receive, plus transitivity. Everything else follows from that one relation — define it first and both clocks become obvious.
- The Lamport limitation stated as a failure: two unrelated writes on different nodes get different Lamport values, so a system using them for LWW will confidently pick a 'winner' between events that were genuinely concurrent, discarding the other with no signal. That's precisely the data loss vector clocks exist to expose.
- Metadata growth is the real-world constraint: a vector with an entry per client is unbounded, which is why Riak switched to dotted version vectors keyed by replica, with pruning of old entries. The cost of pruning is rare false conflicts — acceptable, since a false conflict is merely extra work, while a missed conflict is data loss. That asymmetry is the design principle worth stating.
- Where you meet logical clocks without noticing: Raft term numbers are Lamport clocks; Kafka offsets are a per-partition logical clock; a database row version for optimistic locking is a one-node vector clock. Naming these makes the theory feel like tooling you already use.
- Interval tree clocks / HLC are the modern refinements — HLC especially, because it keeps causality and stays comparable to wall-clock time, which is what most engineers actually want when they reach for a timestamp.