Clock Skew and Causality Violations: Why Distributed Clocks Lie
Why Two Machines Can Never Perfectly Agree on the Time
Physical clocks on distributed machines cannot be perfectly synchronized.
🎯 System Scenario & Requirements
System Goal
Physical clocks on distributed machines cannot be perfectly synchronized.
Actors & Components
- Application or API tier
- Core service under design
- Operator or SRE observer
Functional Requirements
- TLDR: Physical clocks on distributed machines cannot be perfectly synchronized.
- NTP keeps them within tens to hundreds of milliseconds in normal conditions — but under load, across datacenters, or after a VM pause, the drift can reach seconds.
- When systems use wall-clock timestamps to resolve write conflicts (Last-Write-Wins), that drift causes the correct write to lose to a stale one, silently.
Constraints & Assumptions
⚡ Execution Stages & Decision Trace
Stage 1 — The Basics: Clock Synchronization and Its Limits
A clock skew is the difference between the wall-clock time on two different machines at the same instant.
Even machines running NTP on the same local network diverge by 1–10 milliseconds between synchronization events.
Deep Dive
Scenario context
Physical clocks on distributed machines cannot be perfectly synchronized. NTP keeps them within tens to hundreds of milliseconds in normal conditions — but under load, across datacenters, or after a VM pause, the drift can reach seconds. When systems use wall-clock timestamps to resolve write conflicts (Last-Write-Wins), that drift causes the correct write to lose to a stale one, silently. Causality violations are…
This walkthrough focuses on Why Two Machines Can Never Perfectly Agree on the Time.
Before making a design choice, clarify:
- A physical clock is a counter that increments based on the oscillation frequency of a quartz crystal (in most servers) or an atomic resonator (in GPS receivers and atomic clocks).
- Quartz crystals drift — typically by 1 to 100 parts per million — meaning a server's clock can gain or lose between 86 milliseconds and 8.6 seconds per day even without any external disturbance.
- NTP (Network Time Protocol) corrects this by synchronizing server clocks against a hierarchy of reference clocks.
Concepts in play: consistency-replication, transaction-isolation-distributed-acid, design-patterns-gof, database-isolation-levels-anomalies
Stage 1 — The Basics: Clock Synchronization and Its Limits
- A clock skew is the difference between the wall-clock time on two different machines at the same instant.
- Even machines running NTP on the same local network diverge by 1–10 milliseconds between synchronization events.
- Across datacenters or after a VM live-migration pause, that drift can reach seconds.
- Why it matters for distributed systems: - Any operation that uses a timestamp to determine event order will get that order wrong when clocks disagree.
Observable outcome: Why it matters for distributed systems: - Any operation that uses a timestamp to determine event order will get that order wrong when clocks disagree.
Stage 2 — How Clock Skew Breaks Last-Write-Wins Conflict Resolution
- Last-Write-Wins is the simplest conflict resolution strategy: when two replicas hold different values for the same key, the value with the higher timestamp wins.
- The losing value is discarded.
- In a system with perfectly synchronized clocks, this is a reasonable heuristic.
- In a system with clock skew, it silently corrupts data.
Observable outcome: In a system with clock skew, it silently corrupts data.
Stage 3 — Deep Dive: From Lamport Clocks to Vector Clocks
- Internals: Why Causality Breaks Without Synchronized Clocks Causality is the relationship between events where one event causes or enables another.
- If user A posts a message and user B replies to it, A's post causally precedes B's reply.
- A system that delivers B's reply before A's post to some observer has violated causality — the observer sees an answer to a question that hasn't been asked yet.
- This violation can happen even with perfectly synchronized clocks, purely from asynchronous network delivery.
Observable outcome: This violation can happen even with perfectly synchronized clocks, purely from asynchronous network delivery.
Stage 4 — Visualizing Causality Violations and How Vector Clocks Detect Them
- The sequence diagram below shows the classic causality violation: B's reply to A's post arrives at C before A's post does.
- The vector clock attached to each message lets C detect that it is missing a causal predecessor before displaying any content.
- The flowchart below shows how a distributed system should process incoming events using vector clocks to enforce causal delivery:
sequenceDiagram
participant A as "Node A (poster)"
participant B as "Node B (replier)"
participant C as "Node C (observer)"
A->>B: Post "Hello?" with vector [A:1, B:0, C:0]
B->>B: Reply "Yes, hi!" with vector [A:1, B:1, C:0]
B->>C: Deliver reply first (network path is faster)
Note over C: C sees [A:1, B:1, C:0] but has not seen A:1
C->>C: Detect missing predecessor — buffer the reply
A->>C: Deliver original post (delayed path)
Note over C: C now has A:1 — causal predecessor satisfied
C->>C: Display post first, then reply in causal order
flowchart TD
A["Message arrives with vector clock W"] --> B{"Is my local V causally ready\nfor W?"}
B -->|"Yes — all W predecessors already seen"| C["Deliver message to application"]
B -->|"No — missing causal predecessor"| D["Buffer message in causal queue"]
D --> E["Wait for missing predecessor to arrive"]
E --> F["Missing predecessor arrives"]
F --> G["Deliver buffered messages in causal order"]
C --> H["Update local vector clock\nV[j] = max(V[j], W[j]) then V[i]++"]
G --> H
Observable outcome: The flowchart below shows how a distributed system should process incoming events using vector clocks to enforce causal delivery:
Stage 5 — Real-World Cases: Cassandra, Spanner, and the Delete-Before-Write Anomaly
- The Cassandra Delete-Before-Write Anomaly Cassandra's LWW conflict resolution uses the timestamp embedded in each write.
- A particularly dangerous manifestation occurs with the delete-before-write pattern: 1.
- Client writes user.email = "a@example.com" with timestamp T=100.
- Client deletes user.email (tombstone) with timestamp T=101.
Observable outcome: Client deletes user.email (tombstone) with timestamp T=101.
Stage 6 — Choosing the Right Clock Mechanism
Observable outcome: You can explain how “Choosing the Right Clock Mechanism” changes the architecture or implementation path.
End-to-end outcome
After working through the stages, you should be able to explain:
- Physical clocks on distributed machines drift apart at rates of 1–100 ppm; NTP corrects this imprecisely, leaving residual errors of 10 ms to seconds depending on conditions.
- Last-Write-Wins conflict resolution using wall-clock timestamps silently discards the correct write when any node's clock is drifted — the most-recent write in physical time loses to an earlier write with a higher tim…
Alternatives considered
The source focuses on one primary design. A second architecture is not compared, so no alternative is invented here.
Failure and degraded modes
Trade-offs Across Clock Mechanisms
- Detection: Trade-offs Across Clock Mechanisms
- User or operator impact: Trade-offs Across Clock Mechanisms
