Two users edit the same document at 9:03 AM.
No locking. No coordination. Just two clients writing to the same record.
Both changes hit your server 300ms apart. One lands first. The other overwrites it.
User A's work is gone. They never get an error. They just… lose their change.
This is the multi-writer conflict problem. Every collaborative system hits it eventually. Your choices:
A) Last-Write-Wins (LWW) — highest timestamp takes the record. Loser's change disappears silently.
B) Vector Clocks — track causality per replica, detect conflicting versions, surface them to the application for resolution.
C) CRDTs (Conflict-free Replicated Data Types) — data structures that mathematically merge concurrent writes without coordination.
D) Operational Transformation (OT) — transform each operation relative to concurrent operations before applying, keeping intent intact.
Google Docs, Figma, Notion, and DynamoDB all took different bets here.
One of these scales to millions of concurrent writers. One of them works fine until it silently corrupts your data. Two require fundamentally different data models.
Pick one — A, B, C, or D — and tell me why. I'll drop the full breakdown in the comments (including which one Google Docs actually uses and why they almost got it wrong).
Top comments (5)
Answer: C — CRDTs (but the real answer depends on your conflict model — full breakdown below)
C — CRDTs ✅ wins at scale
CRDTs are data structures designed so any two replicas can always be merged — mathematically, without coordination. The key insight: if operations are commutative, associative, and idempotent, conflicts structurally can't exist.
Examples:
• G-Counter: only increments. Merge = take max per replica. Always converges.
• LWW-Element-Set: union of adds + removes with timestamps.
• RGA / YATA (sequence CRDTs): each character gets a unique ID, concurrent inserts are deterministically ordered — this is collaborative text editing.
Figma's canvas runs on CRDTs. Notion's block model is CRDT-based. At millions of concurrent writers across distributed regions, every node converges independently — zero coordination required.
The catch: CRDTs constrain your data model. Not everything maps cleanly. Some operations (like moving a file between directories) are notoriously hard to express without losing intent.
D — Operational Transformation (OT) ⚠️ impressive but hard
OT was Google Docs' original approach. When two operations arrive concurrently, you transform each one relative to the other before applying it. User A inserts at position 5, User B deletes at position 3 simultaneously — OT adjusts A's insert position to account for B's delete. Intent preserved.
That's why Google Docs felt magical in 2009.
But OT is operationally brutal. The transformation functions are notoriously hard to get right — the original OT papers had bugs. Every new operation type adds transformation pairs that grow quadratically. OT also requires a centralized server to sequence operations; it doesn't distribute cleanly.
Modern Google Docs has moved toward a hybrid incorporating CRDT-like ideas. OT alone doesn't scale to full distribution.
B — Vector Clocks ⚠️ honest but incomplete
Vector clocks track causality. Each write carries a version vector — one counter per replica. When two writes have no causal relationship (neither "happened before" the other), you know you have a conflict. Both versions surface to the application layer, which resolves them.
Amazon's internal Dynamo used this. It's correct and transparent. The problem: conflict resolution is now your job. You write merge logic for every data type. For shopping carts it's manageable (union the items). For arbitrary documents? It breaks down fast.
Vector clocks tell you where conflicts are. They don't tell you how to fix them.
A — Last-Write-Wins (LWW) ❌ dangerous
Simple. Brutally simple. Highest timestamp wins. The loser's change vanishes — no error, no notification, just gone.
Cassandra defaults to this. For append-only workloads (metrics, event logs, telemetry) it's totally fine. For anything a human edited? It's silent data loss with a timestamp attached. The treacherous part: users never get an error. Their work just stops being there.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.