Vector Clock
A vector clock tracks causal relationships between events across nodes, detecting concurrency that a single timestamp or counter cannot express.
Definition
A vector clock is a map from node id to a logical counter. Each node increments its own entry when an event occurs and merges the entries it receives from other nodes. Comparing two vectors reveals whether one event happened before the other, after it, or concurrently. Concurrent versions require an application-level conflict resolution rule.
Context and scope
Vector clocks are used in eventually consistent stores, collaborative editing, and distributed caches to detect conflicting updates without a global clock. They are especially useful when network partitions allow two nodes to accept writes independently.
Common misconceptions
- A vector clock provides a total order — it provides a partial causal order and detects concurrency
- Concurrent versions can be ignored — the application must merge or choose a winner
- Vector clocks solve clock skew — they avoid relying on wall clocks, but wall-clock timestamps may still be stored for display
Anti-patterns
- Using a single last-write-wins timestamp for data where lost updates matter
- Growing the vector forever as nodes join without pruning or version vectors
- Treating a concurrent state as an error instead of defining a merge policy
Related concepts
Authoritative source
Causality without a global clock
Two nodes update the same record during a partition. Wall-clock timestamps cannot reliably say which update happened first, because clocks drift. A vector clock records causal history instead. Each node has an entry; an event increments the local entry, and receiving a message merges the other vector by taking the maximum of each entry.
A: {A: 1, B: 0}
B receives A, then updates: {A: 1, B: 1}
A updates independently: {A: 2, B: 0}
Compare the vectors: the second dominates the first (every entry is greater or equal, and one is greater), so {A:1,B:1} happened after {A:1,B:0}. The third and second are incomparable: each has a higher entry for a different node, so the updates are concurrent. The system must merge them or pick a winner according to a defined rule.
Conflict resolution is the real design
Detecting concurrency is only half the job. A shopping cart may merge items, a document editor may keep both edits, and a settings record may use last-write-wins with a tie-breaker. The choice is a product decision. Hiding it behind an arbitrary timestamp can silently lose data. Store the conflicting versions or a merged value, and expose enough information for a user or operator to resolve the conflict when automatic merging is unsafe.
Vector clocks grow with the number of writers. In a large system, an entry per node becomes unwieldy. Version vectors, dotted version vectors, and per-key clocks limit the size. If the system can accept last-write-wins semantics, a simpler hybrid logical clock may be enough; do not add vector clocks without a conflict policy that justifies them.
When to use it
Use vector clocks when concurrent updates are possible, lost updates are unacceptable, and the application can define a merge policy. The advantage is accurate causality without synchronized clocks; the drawback is metadata size and conflict-handling complexity. Compared to a single timestamp, a vector clock is more precise but demands that every writer and reader understand the comparison rules.