Skip to main content

Concepts

Vector clocks for causal versioning

Intuition

Imagine two people editing the same shared shopping list from different phones while offline, then syncing later. If one person's edit clearly happened after seeing the other's (they added to an already-updated list), you can just keep the newer version. But if both edited the original list at the same time without seeing each other's changes, there's no honest way to say one "came after" the other — you have to look at both edits and combine them. A vector clock is a way for the system to tell these two situations apart automatically, without needing synchronized wall-clock time.

How it works

Because Dynamo's sloppy quorums and hinted handoff let it accept writes even when some replicas are unreachable, concurrent writes to the same key can be made without either writer knowing about the other, producing divergent versions of the object. Dynamo tags every version of an object with a vector clock — a set of (node, counter) pairs — that records which nodes have handled updates to that object and how many. By comparing two vector clocks, a node can determine whether one version's clock is a strict descendant of the other's, meaning it causally supersedes it and the older version can be discarded, or whether neither clock dominates the other, meaning the two versions were written concurrently without knowledge of each other and are in conflict. When Dynamo cannot establish a causal order between versions this way, it does not pick a winner arbitrarily or silently merge them; instead it returns all the conflicting versions to the requesting application, along with their vector clocks, and leaves it to the application to reconcile them using domain-specific logic.

In practice

Dynamo's canonical example is a shopping cart: when it cannot causally order two divergent cart versions, it hands both back to the application, which reconciles them by unioning their items rather than losing either customer's addition. Reach for vector clocks (or an equivalent causality mechanism, as adopted by Riak and Voldemort) when a system must stay writeable under partitions and concurrent updates and the application, not the storage layer, is best positioned to resolve genuine conflicts.

Use it in a design

Practice the cases that rely on this concept in the System Design school.