Free — no signup required

Vector Clocks: Detecting Concurrency

3 min read

The Limitation of Lamport Timestamps

Lamport timestamps give you a total order, but they cannot tell you whether two events are causally related or concurrent. This matters enormously in distributed databases: if two clients write to the same key on different replicas simultaneously (concurrent writes), the system needs to detect this conflict and resolve it — not silently pick one and discard the other.

How Vector Clocks Work

A Vector Clock replaces the single integer with an array of integers — one slot per process in the system. If there are N processes, each process maintains a vector of N counters.

Rules:
1. Initialize: Every process P_i starts with a vector of all zeros: [0, 0, ..., 0].
2. Internal event: Process P_i increments only its own slot: V[i] = V[i] + 1.
3. Send event: Process P_i increments its own slot, then attaches the full vector to the message.
4. Receive event: Process P_i receives a message with vector V_msg. It updates each slot to the maximum: V[j] = max(V[j], V_msg[j]) for all j. Then it increments its own slot: V[i] = V[i] + 1.

Comparing Vector Clocks

Given two vector clocks V_A and V_B, you can determine their relationship:

  • V_A < V_B (A happened before B): Every slot in V_A is ≤ the corresponding slot in V_B, and at least one slot is strictly less.
  • V_A > V_B (B happened before A): The reverse.
  • V_A || V_B (Concurrent): Neither is ≤ the other. There exists some slot where V_A[i] > V_B[i] AND some slot where V_A[j] < V_B[j].

The concurrent case (||) is the key capability Lamport timestamps lack. When a distributed database detects two concurrent writes using vector clocks, it knows it has a genuine conflict that requires resolution — not just a reordering issue.

Real-World Usage

Amazon's Dynamo (the internal system that inspired DynamoDB) used vector clocks to detect conflicting writes. When a conflict was detected, Dynamo returned both versions to the application and let the application resolve the conflict (e.g., by merging shopping cart contents). Riak, a distributed key-value store, uses a variant called dotted version vectors for the same purpose.

The limitation of vector clocks is scalability: the vector grows linearly with the number of processes. In a system with thousands of nodes, storing and transmitting a vector of thousands of integers per event becomes expensive. This is why practical systems often use approximations or restrict vector clocks to a small number of replicas.

Interview Tip

A common interview question: "What's the difference between Lamport timestamps and vector clocks?" The precise answer: Lamport timestamps satisfy the clock consistency condition (A → B implies timestamp(A) < timestamp(B)) but not the strong consistency condition (the converse). Vector clocks satisfy both directions — they can detect not just that one event preceded another, but also that two events are concurrent. This makes vector clocks suitable for conflict detection in distributed databases, while Lamport timestamps are sufficient for algorithms that only need a consistent total order (like distributed mutual exclusion).

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free