1If L(A) = 5 and L(B) = 3, what can we conclude about the causal relationship between A and B?
Lamport timestamps are the simplest logical clock mechanism for ordering events in a distributed system. Each process maintains a counter that increments on every event and is updated on message receipt, establishing a partial ordering consistent with the happened-before relation.
Lamport timestamps, introduced by Leslie Lamport in his seminal 1978 paper 'Time, Clocks, and the Ordering of Events in a Distributed System,' provide a mechanism for establishing a consistent ordering of events across multiple processes that do not share a global clock. The paper is one of the most cited in computer science and introduced the happened-before relation, which forms the theoretical basis for understanding causality in distributed systems.
The happened-before relation (denoted ->) is defined by three rules: (1) if events a and b occur in the same process and a occurs before b, then a -> b; (2) if a is the sending of a message and b is the receipt of that message, then a -> b; (3) if a -> b and b -> c, then a -> c (transitivity). Two events are concurrent if neither happened before the other. Lamport's insight was that physical clocks are unreliable for establishing this relation (due to drift and synchronization errors), but a simple logical counter can capture it.
The algorithm is elegantly simple. Each process maintains a counter C, initially 0. Before executing an event, a process increments C. When sending a message, the process attaches its current C value. When receiving a message with timestamp T, the process sets C = max(C, T) + 1. This ensures that if event a happened before event b, then C(a) < C(b). To create a total ordering (breaking ties between concurrent events), each event is tagged with (timestamp, process_id), using process ID as a tiebreaker.
Lamport timestamps are foundational but limited. They guarantee that causal order is preserved (if a -> b, then L(a) < L(b)), but the converse is not true: L(a) < L(b) does not mean a happened before b. To detect concurrency, you need vector clocks. Despite this limitation, Lamport timestamps are sufficient for many practical applications -- total order broadcast, mutual exclusion, and database replication protocols -- where a consistent total ordering is more important than detecting concurrency.
Three Friends Messaging in a Group Chat
Alice (counter=0) sends a message to the group (counter becomes 1, message tagged with 1). Bob (counter=0) receives it and sets his counter to max(0,1)+1=2. Charlie (counter=0) independently sends a message (counter becomes 1). Now Bob sends another message (counter=3). Alice's message (1) happened before Bob's reply (3) -- correctly ordered. But Alice's message (1) and Charlie's independent message (1) have the same timestamp -- they are concurrent. The tiebreaker (Alice's ID < Charlie's ID) gives a total order, but this ordering is arbitrary since the events were truly independent.
Google Spanner (TrueTime + Logical Clocks)
Spanner combines physical timestamps (from TrueTime) with logical ordering rules inspired by Lamport's work. Each transaction is assigned a timestamp that respects both real-time ordering and happened-before causality. Spanner's commit-wait protocol ensures that if transaction A commits before transaction B starts, A's timestamp is strictly less than B's -- a real-time extension of Lamport's guarantee.
Apache Kafka
Kafka uses monotonically increasing offsets within each partition, which function similarly to Lamport timestamps for events within a partition. The offset guarantees a total order of messages within a partition. Cross-partition ordering is not guaranteed, reflecting the fact that events in different partitions may be concurrent. When a consumer processes messages from multiple partitions, it must handle the lack of cross-partition ordering explicitly.
Distributed Databases (CockroachDB, YugabyteDB)
CockroachDB uses hybrid logical clocks (HLC) -- a combination of physical timestamps and Lamport logical counters. The physical component provides rough real-time ordering, while the logical component ensures that causally related events at the same physical timestamp are correctly ordered. HLCs provide 'good enough' ordering for most operations while avoiding Spanner's TrueTime hardware requirements.
| Aspect | Description |
|---|---|
| Simplicity vs Expressiveness | Lamport timestamps are trivial to implement (one integer counter, one max operation) and add minimal overhead. However, they cannot distinguish between concurrent events and causally ordered events with different timestamps. If your system needs conflict detection, you must use vector clocks at the cost of O(N) space. |
| Total Order vs Causal Order | Lamport timestamps provide a total order (every pair of events is comparable), which is convenient for algorithms that require a single linear history. But this total order is arbitrary among concurrent events -- it does not reflect any real causal relationship. Vector clocks provide only a partial order but correctly identify concurrency. |
| Space Efficiency vs Information Content | A single integer (8 bytes) carries much less information than a vector of N integers (8N bytes). Lamport timestamps are ideal for systems where space and bandwidth are constrained and total ordering is sufficient. Vector clocks are necessary when detecting and resolving conflicts between concurrent updates. |
| Physical vs Logical Time | Lamport timestamps have no connection to real-world time -- a timestamp of 1000 tells you nothing about when an event occurred. Hybrid logical clocks (HLCs) combine physical and logical components to provide both causal ordering and approximate real-time information, at the cost of slightly more complexity. |
Lamport's Mutual Exclusion Algorithm
Scenario
In a distributed system with N processes sharing a resource, mutual exclusion must be achieved without a central coordinator. Each process needs to enter a critical section, and only one process should be in the critical section at any time. The solution must be fair (every request is eventually granted) and must not rely on physical clock synchronization.
Solution
Lamport's distributed mutual exclusion algorithm uses Lamport timestamps and a total-order broadcast. When a process wants to enter the critical section, it timestamps its request with its Lamport clock and broadcasts it to all other processes. Each process maintains a priority queue of requests ordered by timestamp (with process ID tiebreaker). A process enters the critical section only when its request is at the head of the queue and it has received acknowledgments from all other processes with timestamps greater than its request timestamp.
Outcome
The algorithm guarantees mutual exclusion, deadlock-freedom, and fairness using only logical clocks and message passing -- no physical clock synchronization required. It requires 3(N-1) messages per critical section entry (request + N-1 replies + release broadcast). While not optimal in message complexity (Ricart-Agrawala reduces it to 2(N-1)), Lamport's algorithm was the first to demonstrate that logical clocks alone could solve distributed coordination problems.
See Lamport Timestamps in action
Explore system design templates that use lamport timestamps and run traffic simulations to see how these concepts perform under real load.
Browse Templates1If L(A) = 5 and L(B) = 3, what can we conclude about the causal relationship between A and B?
2What is the update rule when process P receives a message with timestamp T?