Two servers write to the same key. Which write came second? The obvious answer is to compare timestamps, and the obvious answer is wrong — clocks on different machines drift, and a write that genuinely happened later can carry an earlier timestamp. Resolving conflicts by timestamp means silently discarding the wrong update.
Vector clocks replace time with causality. Instead of asking which happened later, they ask whether one event could have known about the other.
What changed in 2026
- Hybrid clocks became the pragmatic default. Combining physical time with logical counters gave usable ordering with bounded metadata, displacing pure vector clocks in many systems.
- Cloud time services improved. Tightly synchronized clocks with known error bounds made time-based ordering viable in more contexts, though not universally available.
- Version vectors stayed the practical form. Tracking per-replica rather than per-client kept the metadata bounded for storage systems.
- The lesson kept being relearned. Timestamp-based conflict resolution silently losing writes remained a recurring incident category.
How the comparison works
Each node maintains a counter for every node it knows about. When it performs an event it increments its own counter. When it receives a message it takes the element-wise maximum of its vector and the sender's, then increments its own.
Comparing two vectors gives three possible answers:
| Comparison |
Meaning |
| Every element of A is less than or equal to B, and at least one is strictly less |
A happened before B |
| The reverse |
B happened before A |
| Neither dominates |
A and B are concurrent |
That third case is the valuable one. Concurrent means neither event could have known about the other, which means they are a genuine conflict that requires a decision — not an ordering that a timestamp comparison would have invented.
What they do not do
Vector clocks detect conflicts. They do not resolve them. Discovering that two writes were concurrent tells you that picking either one silently is wrong; it does not tell you what to do instead.
The options are the usual ones: surface both versions to the application or the user, merge them with domain logic, or apply a deterministic rule and accept the loss knowingly. That last option is what last-write-wins does, and doing it knowingly after detecting concurrency is very different from doing it accidentally because timestamps happened to differ.
For data types where automatic merging is possible, CRDTs go further — they make concurrent operations merge deterministically rather than requiring resolution at all.
The practical constraint is size. A vector carries an entry per node, so in a system with many participating nodes the metadata becomes substantial relative to the data. Version vectors, tracking replicas rather than clients, keep this bounded. Hybrid logical clocks bound it further by combining physical time with a small counter, accepting slightly weaker guarantees for much smaller metadata.
Common mistakes
- Ordering distributed events by wall clock. Silently loses writes.
- Treating concurrency detection as resolution. It tells you there is a conflict, not what to do.
- Per-client vectors in a system with many clients. Unbounded metadata growth.
- Assuming synchronized clocks. Even with good synchronization, error bounds matter.
- Using them where a single log would do. A sequencer gives total order far more simply.
FAQ
Are vector clocks still used?
In storage systems needing conflict detection without coordination, yes. Many systems have moved to hybrid logical clocks for smaller metadata.
What is the difference from a Lamport timestamp?
A Lamport timestamp gives a total order consistent with causality and cannot distinguish concurrent events from ordered ones. Vector clocks can.
Do I need this with a single database?
No. A single database provides ordering. This is for systems where writes happen in several places without coordination.
What about tightly synchronized cloud clocks?
Where available with known error bounds, they enable time-based ordering with explicit uncertainty windows. That is a different and often simpler approach where the infrastructure supports it.
Where to go next
For automatic merging, read CRDTs explained. For coordinated distributed operations, saga pattern explained, and for reliable event delivery, outbox pattern explained.