I use Lamport time to explain ordering when wall clocks cannot be trusted. It helps me reason about which event could have influenced another without pretending servers share one perfect clock.
It tracks happened before, not exact time
When I talk about "It tracks happened before, not exact time", I am really asking what Lamport Time does when a message is late, duplicated, or missing.
Each node increments its counter for local work. When it sends a message, it includes the counter. The receiver moves its counter forward if needed. This gives a safe ordering rule for cause and effect.
Message order example
I use "Message order example" to keep Lamport Time grounded in a real system, because abstract patterns are too easy to agree with and too hard to operate.
Service A creates an order at logical time 5 and sends a message to Service B. Service B moves to time 6 before reserving inventory, so the reservation is ordered after the order.
Logical clock code
When I show "Logical clock code", I want the code in Lamport Time to reveal the production decision, not just the syntax.
A receiver moves its logical clock forward when a message arrives:
long onReceive(long localClock, long receivedClock) {
return Math.max(localClock, receivedClock) + 1;
}
The receive rule preserves causal order by moving the local clock past both the local value and the received value. It orders events without needing synchronized wall clocks.
Sequence diagram: logical time moves with the message
The reservation is known to happen after the order because the message carried the logical counter.
The ordering rule
- Use logical clocks when cause and effect matters more than real time.
- Do not use Lamport time to detect concurrent updates by itself.
- Pair it with clear ordering rules for consumers.