Case study
Design Google Docs Collaborative Editing
Enable real-time multi-user document editing with conflict-free merging and version history.
Requirements
- Functional: create/edit documents; real-time sync; cursor presence; version history
- Support 50 concurrent editors per doc; offline edit with merge on reconnect
- Non-functional: operation propagation p99 < 200ms; no lost keystrokes
- Consistency: eventual convergence — all clients see same final document
- Scale: 100M docs; 10M DAU; avg 10 KB doc size
Back-of-envelope Estimation
| Metric | Calculation | Result |
|---|---|---|
| Ops/sec global | 10M users × 2 ops/sec active fraction 10% | ~2M ops/sec |
| Hot doc ops | 50 editors × 2 ops/sec | 100 ops/sec per hot doc |
| Storage | 100M × 10 KB snapshots | ~1 TB (+ revision history ~5×) |
| WebSocket connections | 10M × 5% editing | 500K concurrent |
API Design
| Interface | Description |
|---|---|
| WS /v1/docs/{docId}/sync | Send/receive operations: insert, delete, retain |
| GET /v1/docs/{docId} | Snapshot + revision vector for catch-up |
| GET /v1/docs/{docId}/history | List revisions with timestamps |
| POST /v1/docs/{docId}/snapshot | Periodic compaction checkpoint |
Data Model
| Entity | Content |
|---|---|
| operations_log | doc_id, op_id, user_id, op_type, position, char, ts — append-only |
| snapshots | doc_id, revision, content_blob — S3 every N ops or 5 min |
| presence | doc_id, user_id, cursor_pos, color — Redis ephemeral |
| revision_vector | doc_id → { user_id: seq } — for OT ordering |
High-level Design
Clients ◄──WebSocket──► Doc Server (per-doc shard routing)
│
Apply OT/CRDT ──► append op log ──► broadcast to peers
│
Snapshot Worker (compact log periodically)
│
Object Store (snapshots + op log segments)Deep Dive: Operational Transform
Each edit is an operation (insert 'x' at index 5). Server assigns global sequence; transforms concurrent ops against each other so insert indices remain consistent. Client applies remote ops locally; local buffer holds unacknowledged ops.
OT vs CRDT
OT (Google Docs classic) needs central server for ordering. CRDTs (Yjs, Automerge) allow P2P but use more metadata. Server-authoritative OT is simpler to reason about in interviews.
Deep Dive: Doc Sharding & Hot Documents
- Route doc_id to dedicated server via consistent hash — single writer per doc
- Hot doc (100 editors): shard not needed — 100 ops/sec is trivial for one server
- Very hot (company-wide): read-only broadcast mode + comment-only for viewers
- Catch-up: new client fetches snapshot + ops since snapshot revision
Failure Modes & Monitoring
| SLO | Target |
|---|---|
| Op propagation p99 | < 200ms |
| Convergence | 100% within 1 sec of last edit |
| Zero data loss on server crash | Ops persisted before ack |
Persist op to log before ACK to client. On server crash, replay log from last snapshot. Monitor op log growth, snapshot lag, client divergence reports.