Offline-first and sync

What is last writer wins?

Last writer wins (LWW) is a conflict rule that keeps the write with the highest timestamp and discards the others. Every replica applies the same comparison, so all copies settle on the same value, but the losing write disappears without anyone being told.

Learning objectives

After reading this article you will be able to:

  • Explain how last writer wins picks the same winner on every replica
  • Compare wall clocks and logical clocks for deciding which write is last
  • Choose when last writer wins fits and when another merge rule is better

How it works

Every write carries a timestamp. When two replicas exchange versions of the same value, each keeps the one with the higher timestamp and throws the other away. Because every replica runs the same comparison on the same inputs, they all keep the same winner, whatever order the writes arrived in.

The idea is old. Paul Johnson and Robert Thomas described it in RFC 677, a working paper on keeping duplicate databases on the ARPANET. Each change carried a timestamp made of a time and the identifier of the site that made it, compared by time first and site second. Each site kept whichever change was more recent, so once every change had reached every site, all copies held the same latest value.

Shapiro, Preguiça, Baquero, and Zawirski later specified the same rule as the LWW register, and spelled out what the timestamps must be for it to work:

  • Unique. No two writes may share a timestamp, or replicas could pick different winners.
  • Totally ordered. Any two timestamps can be compared.
  • Consistent with causality. If one write happened before another, it has the smaller timestamp, so a later edit is never beaten by the one it replaced.

They suggest a per-replica counter joined to a unique replica identifier. The counter orders writes, and the identifier breaks ties. This is exactly the construction behind a Lamport timestamp.

Where it is used

Last writer wins is common because it is cheap and predictable.

  • Apache Cassandra timestamps every mutation, including deletes, and resolves each column of a row by last write wins. The timestamp comes from the client or, if the client gives none, the coordinator node’s clock.
  • Amazon DynamoDB global tables resolve writes to the same item in different Regions by keeping the one with the latest internal timestamp, per item.
  • Automerge uses last writer wins when two people set the same property at once. Its “last” is based on an operation ID made of a counter and an actor ID, not on wall-clock time, and the losing values are kept in a separate conflicts object rather than deleted.

Which clock decides “last”

The rule is only as good as its timestamps. Wall clocks are the obvious choice and the riskiest. Johnson and Thomas already noted that time of day is often set by hand, and so prone to error. Cassandra’s documentation says plainly that its correctness depends on the clocks, and tells operators to run a time synchronisation process such as NTP. A phone that has been offline for days is not under anyone’s NTP discipline. If its clock runs fast, its edits beat newer ones; if it runs slow, its edits lose to older ones.

Logical clocks avoid that failure but change what “last” means. A counter-based timestamp is consistent with causality, so an edit made after seeing another always wins over it. For two edits made apart, though, the order is arbitrary but agreed. Lamport’s 1978 paper gives the example of a person who issues a request on one computer, then telephones a friend who issues a second request on another. The system can order the second request first, because the phone call happened outside it. A device returning from a long time offline can see the same effect: an edit it made later in real time can still lose.

What it throws away

The real cost of last writer wins is silent data loss. When two writes are concurrent, one of them is discarded and nobody is told. That is fine when only the most recent value matters, and harmful when both writes carried information.

How much it loses depends on how finely the rule is applied:

  • Per record. Two people editing different fields of the same record collide, and one person’s edit vanishes.
  • Per field or key. Edits to different fields both survive. Only edits to the same field compete.

Offline Protocol’s replicated documents (DataStore) show the trade-off in their own rules. Map collections use last writer wins per key, and the shared state guide warns that map values are replaced as a whole, so fields that must merge independently belong in separate keys rather than in one JSON string.

When to use it, and when not to

Last writer wins suits values where only the latest one matters:

  • statuses, flags, and settings
  • the current position of something on a map
  • a name or title that people rarely edit at the same time

It is the wrong rule when every write carries information:

  • Counts. Two devices that each add to a total should both count. A counter type that sums increments from every replica fits better.
  • Collections. Two people adding items to a list should both see their items kept. Set and list types that merge additions fit better.
  • Shared text. Two people typing in the same note should both keep their words. A text type that merges at character level fits better.
  • Records you cannot afford to lose. Keeping both versions, as Automerge does in its conflicts object, lets a person choose.

Detecting that two writes were concurrent, rather than one replacing the other, needs more than a single timestamp. A vector clock can tell the two cases apart, which is what lets a system keep both versions instead of picking one. How are sync conflicts resolved? compares the options side by side.

Frequently asked questions

Does last writer wins need synchronised clocks?

Only if "last" is decided by wall-clock time. Systems that use a logical clock, such as a counter plus a replica identifier, get a consistent winner without synchronised clocks, but the winner is then the latest in logical order, not always the latest in real time.

Is last writer wins a CRDT?

Yes, when it is applied as a register with unique, totally ordered timestamps. Shapiro and colleagues specify it as the LWW register, and Apache Cassandra describes each row as an LWW element set.

Sources

Build it with Offline Protocol

In Offline Protocol's replicated documents, map collections use last writer wins per key, while lists, text, and counters use other merge rules. The shared state guide lists each rule and shows how to split fields so unrelated edits do not collide.

Read the shared state guide