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
I use this section to force the failure case into the conversation, not just the clean path.
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
This example is useful because it shows who owns the work and what breaks when the happy path disappears.
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
I use the code here to show the decision boundary, not just 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.