Distributed Systems for Backend Engineers · Data Distribution and Agreement
Conflict Resolution and CRDTs
Merge concurrent updates in multi-leader and offline systems.
When multiple replicas accept writes (multi-region, offline-first apps, collaborative editing), concurrent updates conflict. Strategies: last-write-wins (simple, loses data), application merge (custom logic or user resolution), and CRDTs — data types that merge deterministically without coordination (G-Counter, PN-Counter, OR-Set, LWW-Register, sequence CRDTs for text). Libraries: Automerge, Yjs; databases: Riak, Redis Enterprise CRDBs, Azure Cosmos DB conflict policies.
Conflict strategies
| Strategy | Data loss? | Complexity | Use for |
|---|---|---|---|
| Last-write-wins | Yes (concurrent writes) | Low | Caches, idempotent overwrites |
| Custom merge / user resolves | No (if done right) | Medium–high | Documents, records |
| CRDT counters/sets | No | Medium | Likes, carts, flags |
| Sequence CRDTs (Yjs/Automerge) | No | Library-provided | Collaborative text, offline apps |
class GCounter:
def __init__(self, node_id: str):
self.node_id, self.counts = node_id, {}
def increment(self, n: int = 1):
self.counts[self.node_id] = self.counts.get(self.node_id, 0) + n
def value(self) -> int:
return sum(self.counts.values())
def merge(self, other: "GCounter"):
for node, c in other.counts.items(): # element-wise max: commutative, idempotent
self.counts[node] = max(self.counts.get(node, 0), c)
import * as Y from "yjs";
const doc = new Y.Doc();
const todos = doc.getArray<string>("todos");
todos.push(["Buy milk"]); // offline edits on two devices…
const update = Y.encodeStateAsUpdate(doc);
Y.applyUpdate(otherDoc, update); // …merge deterministically when they sync
Common pitfalls
- LWW on wall clocks for important data.
- Ignoring conflicts in offline-first apps.
- Rolling your own CRDTs for text editing.
Key points
- Concurrent writes need a merge strategy
- CRDTs merge without coordination
- Use Yjs/Automerge for collaboration
Further reading: crdt.tech
Practice questions
What properties make CRDT merges safe in any order?
Answer
Merge is commutative, associative and idempotent, so replicas converge regardless of delivery order or duplication.
Why is last-write-wins risky for user data?
Answer
Concurrent updates are resolved by timestamp (with clock skew), silently discarding one user's changes.
Open in the app to mark lessons complete, take notes and track your progress.