Mehdi Akiki
Published on

Last-Write-Wins Is a Data-Loss Strategy

Authors
  • Mehdi Akiki avatar
    Name
    Mehdi Akiki
    Twitter

Reference · Derived state

Two systems can edit the same customer. Both change it at almost the same time. Now you have two versions, and you must pick one. The simplest rule is last-write-wins: keep the newest, drop the rest.

It is easy to build and easy to explain. It is also a strategy for losing data, and many people choose it without noticing that part.

How it works

Every write carries a time or a version. When a conflict happens, you compare, and the newer write replaces the older one.

write 1 (t=10): { name: "Sam", phone: "111" }
write 2 (t=11): { name: "Samuel", phone: "111" }
result: write 2 wins -> { name: "Samuel", phone: "111" }

Simple. But look closer at what "wins" means.

The hidden cost

Last-write-wins replaces the whole record, not one field. Imagine two people edit the same customer at the same time:

write 1 (t=10): changes phone to "222"
write 2 (t=11): changes name to "Samuel"
result: write 2 wins -> the new phone "222" is gone

Write 2 did not touch the phone, but because it is newer, it overwrites everything. One person's change just disappeared, with no error and no log. The system did exactly what you told it: keep the newest, drop the rest.

The clock problem

"Newest" depends on a clock, and clocks lie. Two servers do not agree on the exact time, and a clock can even jump backward. So the write that "wins" can be the one that actually happened first. With last-write-wins, a wrong clock means wrong data, quietly.

When it is fine, and when it is not

Last-write-wins is a fine choice when conflicts are rare and the data is cheap to lose, like a "last seen" time or a UI preference.

It is a bad choice for money, inventory, or anything where a lost write is a real problem. There you want a rule that detects the conflict instead of hiding it: version vectors, or, for some kinds of data, types that merge by design (CRDTs).

The honest way to use last-write-wins is on purpose, with open eyes: "I accept that the losing write is gone." If you cannot accept that, do not use it. When you keep two systems in sync in two directions, this is the first decision you have to make.