Skip to main content

Conflict Resolution Strategies

Introduction

Three lessons of machinery have left you holding seven tools: keep-both siblings, self-merging counters and sets, transformed operations, and the blunt instruments that never left — last-write-wins, union, refuse, ask a human. What you don't have yet is the thing a staff engineer actually gets paid for: the judgment for matching tool to data, on purpose, before the incident does it for you.

This lesson is that judgment, built in three moves: the shelf with honest price tags, the short list of questions that pick a strategy for you, and an audit of the defaults already running in your stack — because every store you operate has answered this question, whether or not anyone at your company ever did.

Seven conflict tools on three shelves, each with a hanging price tag. Top shelf, the blunt: last-write-wins (a clock face), union (two circles joined), refuse (a barred door). Middle shelf, the structural: siblings (two chips side by side), CRDT (a self-fusing value), transform (a T box). Bottom shelf, alone: ask a human (a person beside two versions). Law band: priced by what it can lose and what it demands.

The Shelf, Priced

Every strategy is a claim about what your data can afford to lose. Read the tags.

Last-write-wins. Converges perfectly, instantly, by destroying a concurrent write. For a true snapshot — a display name, a sensor's latest ping — that loss is not just tolerable but correct: the newest sighting is the answer. For anything that accumulates, it's silent data loss wearing a policy's costume. Price: one write, chosen by a clock.

Union. Nothing added is ever lost; deletions lose their memory and resurrect. The famous cart took that trade on purpose: a ghost item beats a lost sale. Price: the delete's meaning.

Refuse. No second answer is ever accepted, so no conflict is ever born. This is the payment path's answer from CAP, Properly (decline rather than double-charge), and it spends availability to buy singleness. Price: serving someone "no".

Siblings, merged at read. The store keeps both and hands them to the one party with context: your application. Nothing is lost, nothing resurrects unannounced, and every reader inherits homework. Price: simplicity, deferred to read time.

CRDT types. For counts, sets, flags, maps of the same: the merge is a law of the shape, exact under any order, grouping, or repeats. Price: the metadata mortgage of slots, tags, tombstones.

Transformed operations. For sequences, where position is meaning: intentions preserved surgically. Price: an ordering server (or per-character identities and their per-keystroke toll), plus a transform matrix that grows with every new kind of edit.

A human. The only resolver that knows what was meant instead of inferring it. Slow, unscalable per conflict, and sometimes simply correct. Price: latency, and a queue someone must actually watch.

The price column: seven strategy rows, each naming what it spends. Last-write-wins spends a concurrent write. Union spends the memory of deletes. Refuse spends availability. Siblings spend simplicity, deferred to readers. CRDTs spend metadata. Transform spends serverlessness. A human spends latency. Foot band: nothing is free; spend on purpose.

The Questions That Pick For You

The shelf looks like seven choices. Asked in the right order, it's almost never more than one.

First: could both answers be true? If not (one seat, one username, one remaining ticket), stop shopping. Nothing on the merge shelf helps a contradiction; you refuse, you coordinate through the one-answer door, or you park both versions for a person. Every strategy below this line assumes compose-shaped data.

Second: what shape is the field? The snapshot-or-accumulation test from Version Conflicts does most of the work. A snapshot earns last-write-wins honestly. An accumulation forbids it. If the accumulation is a count, set, or flag, the shape itself can carry the merge: CRDT. If it's a sequence, position is meaning and you're in the text lane: transform behind a server, character identities offline.

Third: who knows the meaning? When a correct merge depends on what a cart or a schedule is — rules the shape can't see — keep siblings and let the application merge at read. When not even the application can say, the answer is the person who typed it.

And three meta-rules that outrank the tree. A default is not a decision: if you never chose, you still shipped a strategy, just nobody's. Choose per field, not per system: the granularity dial from The Conflict Problem means one object can honestly carry a last-write-wins photo, a CRDT counter, and a sibling-merged cart. And every choice re-takes the two-question exam: does it converge, and does it keep what people meant?

The strategy decision tree, three ordered forks. Could both answers be true? No routes to refuse · human, no merge exists. Yes drops to the shape fork: snapshot to last-write-wins, honest here only; count·set·flag to CRDT types, merge is a law; sequence to the text lane, OT or char IDs. Accumulations drop once more: who knows the meaning? A rule routes to union, adds never lost; the app routes to siblings, merged at read. Law band: a default is not a decision.

See It, Decide It: The Strategy Ladder

Below, the discipline as a machine. Answer four questions about one field of your data and watch the ladder slide to the least machinery that answers honestly, with warnings wherever your answers hide a price. Run your real schema through it: the profile photo, the cart, the like counter, the shared document, the seat map. Five fields, likely four different rungs — which is the point.

Four questions about one field of your data — could both answers be true, what shape is it, who can judge a merge, must it work offline — and the ladder slides to the least machinery that answers honestly, from last-write-wins up to refuse-and-coordinate. Warnings pop where your answers hide a price: resurrection for unions, aftercare for siblings, the metadata mortgage, the contradiction that no ladder rung can merge. Try your own fields: a profile photo, a cart, a like counter, a shared doc, a seat map.

The Defaults You Already Run

Now the audit, because production has been answering this question without you.

Cassandra resolves every concurrent write per column, by timestamp, last-write-wins, as the default: the exact machinery whose crime scene you walked in Version Conflicts. Riak shipped the opposite conviction: since version 2.0, keeping siblings is the default. The store that popularized keep-both decided that destroying by default was the greater evil, and flipped the switch for everyone. CouchDB picks a deterministic winner so every replica agrees, and keeps the losers on disk for the application — converge first, preserve the evidence. And Dropbox, facing two versions of your file, refuses to guess: it keeps both and names one conflicted copy, with your machine's name on it: a planet-scale ask-a-human queue disguised as a filename.

Four mature systems, four different answers, each defensible for its data. The audit question for your own stack is one sentence: for each field, which strategy did you choose — and which did you merely receive?

Four defaults you already run, as product cards. Cassandra: per-column timestamps, last-write-wins by default. Riak 2.0: flipped its default to keep siblings — allow_mult true. CouchDB: deterministic winner, losers kept on every replica. Dropbox: refuses to merge and saves a conflicted copy with your device's name on it. Band: which of these did you choose, and which did you merely receive?

Key Takeaways

  • Seven tools, each priced by what it spends: a concurrent write, the memory of deletes, availability, simplicity, metadata, serverlessness, or latency. Nothing on the shelf is free.
  • Three questions do the picking: could both answers be true (contradictions leave the shelf entirely); what shape is the field (snapshot, accumulation, compose-shape, sequence); who knows the meaning (a rule, the app, a person).
  • The meta-rules outrank everything: a default is not a decision; choose per field, not per system; every choice re-takes the exam — converge, and keep what people meant.
  • Production already voted, differently: Cassandra destroys by default, Riak keeps by default, CouchDB converges and preserves, Dropbox asks you. Your stack is running strategies right now; the only question is whether they're chosen.

One scene has been quietly waiting through this whole section: the phone. A week offline, a queue of edits, then an airport lounge and a sync. Every tool in this lesson assumed the conflict was already found — but finding it, queuing the edits, replaying them in order, surviving a sync that dies halfway, and counting every operation exactly once is its own machine, and it's the one in your pocket. That loop is next: Offline-First Sync.