When Timestamps Disagree with Causality — Clock Skew Loses a Write
Figure 9-3: client B's increment happens after client A's write, yet carries a smaller timestamp, so last-write-wins throws it away
Node 1 · clock 42.004
client A writes x = 1
timestamp = 42.004 s
replicates to node 3 + 2
Node 3 · clock 42.003
client B increments x = 2
timestamp = 42.003 s
skew under 3 ms — still wrong
Node 2 · receives both
keeps the greatest timestamp
x = 1 (42.004) wins
x = 2 (42.003) is discarded
x=1
x=2
x=1 also replicates directly to node 2
① Real time — the causal order
A writes x=1
B increments to x=2
B reads A's value first, so B is causally later
time flows right
② Timestamp order — what last-write-wins actually sees
x=2 stamped 42.003
x=1 stamped 42.004
LWW keeps this one
LWW drops this one
the two orders disagree
Result at node 2: x = 1 survives, x = 2 is discarded — the increment is lost.
No error is raised. The data silently disappears, and a node with a lagging clock cannot overwrite a faster node's value until the skew has elapsed.
Safer ways to order writes
• read the current timestamp first and stamp strictly above it (one extra round trip) — Cassandra/Scylla instead use the client clock and accept the risk
• logical clocks (Lamport, version vectors) record ordering without reading any clock; Spanner instead waits out the clock's uncertainty interval