When a conflict happens
Two changes conflict when they touch the same data and neither device knew about the other’s change when it made its own. Computer scientists call these changes concurrent. It does not mean they happened at the same moment: a technician might edit a job on Monday in a basement and a dispatcher might edit it on Tuesday at the office, and if the technician’s phone has not synced yet, the two edits are still concurrent.
Many apparent conflicts are not real. If one person changes a job’s address and another changes its notes, the edits touch different fields and can both be kept. How finely the data is split decides how often true conflicts occur.
Last writer wins
The simplest rule keeps whichever change is newest and discards the other. It is predictable and easy to build, and it is fine for values where only the latest matters, such as a status or a setting.
It has two weaknesses. It loses data silently: the earlier edit is gone, and nobody is told. And “newest” depends on clocks, which drift on devices that have been offline. Systems that use last writer wins often order changes with logical clocks, building on Lamport’s work, plus a fixed tie-breaker such as a device identifier, so that every replica picks the same winner even when wall clocks disagree.
Applying it per field rather than per record makes it far less destructive, because two edits to different fields of the same record no longer collide.
Keep both and let someone choose
Another approach keeps every conflicting version and asks a person, or the application, to decide. Apache CouchDB works this way: it picks a winning revision with a deterministic algorithm, so every replica shows the same one, but keeps the losing revisions so the application can find and resolve them.
This never loses data, which matters for records like inspection findings or medical notes. The cost is that someone has to resolve conflicts, and an app that surfaces too many of them becomes tiring to use.
Merge automatically
Some data can be merged without choosing a winner at all, if it is stored in a structure built for merging. Conflict-free replicated data types (CRDTs) are designed so that concurrent changes can be combined in any order and always produce the same result.
- Counters add up increments from every device, so two people each adding three items gives six, not three.
- Sets can keep every item that was added, with clear rules for items one device added and another removed.
- Lists and text keep insertions from both sides in a consistent order, so two people typing in the same document both keep their words.
Collaborative editors take a related route called operational transformation, which adjusts each change against the others it crossed with, usually with a server keeping the order.
Let an authority decide
Some conflicts should not be merged automatically. Two people booking the last seat, or two technicians taking the last spare part, will merge cleanly into a state that breaks a business rule. These need an authority, usually the backend, that checks the rule when it receives the changes and rejects one of them. The app then has to tell the person whose action was rejected and offer a way forward.
Choose a rule per kind of data
There is rarely one right answer for a whole app. A good design picks the rule for each kind of data:
| Kind of data | Usually best | Why |
|---|---|---|
| Status, settings, single values | Last writer wins, per field | Only the latest value matters |
| Counts and tallies | Counter merge | Every device’s increments should count |
| Notes and shared text | Text merge | Nobody’s words should disappear |
| Findings, records, evidence | Keep both versions | Losing data is worse than resolving by hand |
| Stock, bookings, assignments | An authority decides | A business rule must hold across everyone |
Two habits reduce conflicts whatever the rule. Split records into independent fields instead of storing them as one block, so unrelated edits do not collide. And refer to items by stable identifiers rather than by position, so an insertion on one device does not shift what another device meant.