Back to System design

Design a Collaborative Editor (Google Docs)

hard
Scale: Sub-100ms keystroke echo; 100-1000s concurrent editors per doc max Storage: Op log + snapshot per doc; CRDT metadata can be large Google, Microsoft, Notion
Case StudyRealtimeCRDT / OT

A collaborative editor like Google Docs, Figma, Notion, Office 365 lets multiple users edit one document simultaneously, with each user's changes appearing in others' views within tens of milliseconds, intent preserved, offline-friendly, with history.

ScaleSub-100ms keystroke echo; 100-1000s concurrent editors per doc max
StorageOp log + snapshot per doc; CRDT metadata can be large

Key Concepts

1
1. OT vs CRDT. Operational Transformation (Google Docs, Jupiter algorithm): clients send ops with revision numbers; server transforms (e.g., shift positions) so concurrent inserts both apply correctly. Server-canonical, smaller payload. Famously hard to implement right. CRDT (Yjs, Automerge, Figma): each character has a unique ordered ID; merge is associative + commutative. P2P-friendly, larger metadata per character (delta encoding helps).
1. OT vs CRDT.
2
2. Server architecture. Each doc has a designated owner on a server. Clients connect via WebSocket; ops flow client → owner → broadcast. Owner persists ops to a log + periodically snapshots state. Snapshot + log = durable. Reconnect replays missed ops. Permissions checked on join; read-only viewers see broadcasts but ops are rejected.
2. Server architecture.
3
3. Presence is separate. Cursor positions, selections, who's online — ephemeral, broadcast via Redis pub/sub. Doesn't need durability. Bandwidth budget smaller than for ops, but updates more frequent (every cursor move).
3. Presence is separate.
4
4. Scaling and edge cases. Hot docs (popular shared doc with 300 editors): the owner is a hot shard. Mitigate via region-sharded owners or CRDT for P2P. Large docs (10 MB+): section-level CRDTs let chapters be edited independently. Emoji + RTL + combining marks: ops on grapheme clusters, not bytes. Undo: per-user history filter (only your own changes) plus global; capped at N entries or days.
4. Scaling and edge cases.
5
5. References. Google Docs: server-mediated OT, battle-tested 15+ years. Microsoft Word collaborative: hybrid OT-like. Figma: in-house CRDT-like for vector graphics, published talks. Notion: CRDT-based blocks, uses Yjs internally for some surfaces. Replit multiplayer: CRDT for code collaboration.
5. References.

High-level design

Client opens WebSocket to doc owner.
Client sends ops with revision number.
Owner orders ops (OT) or merges (CRDT), persists, broadcasts to others.
Snapshot + op log durable.
Presence on separate channel (Redis pub/sub).
Permission checked on join.
Reconnect: replay missed ops.

Components

  • WebSocket gateway with doc → owner routing.
  • Doc owner service (one per doc; sharded by doc_id).
  • Op log + snapshot store (Postgres / KV).
  • Presence service (Redis pub/sub).
  • Permission service (ACL on doc).
  • Export / print pipeline (PDF, Word).
  • Search indexer (async).

OT in depth

Operations: insert(pos, char), delete(pos, len).
Transform function: T(op1, op2) returns op1' that has same effect as op1 if applied after op2.
Server-mediated (Jupiter algorithm): clients send ops with revision; server transforms and broadcasts.
Convergence: all clients end up at same state.
Intent preservation: insert goes where user meant.
Hard edge cases: nested transforms, attribute conflicts.

CRDT in depth

Unique IDs per element (typically (author, counter)).
Concurrent inserts merge by ID order.
Concurrent deletes (tombstones) idempotent.
Associative + commutative merge → P2P friendly.
Cost: metadata per character; delta encoding mitigates.
Yjs (Y-CRDT), Automerge are widely-used libraries.

Trade-offs

OT: well-understood, smaller payload; hard to implement correctly.

CRDT: simpler reasoning, P2P, larger payload, harder to add later.

Single owner per doc: simple ordering; hot shard for big docs.

Distributed owners (CRDT): scales but coordination across owners needed for snapshot/sync.

Snapshot + log: bounded log size; snapshot timing matters.

Large docs: section-level CRDTs or chunked owner per section.

Real-world systems

  • Google Docs: server-mediated OT (Jupiter algorithm). Battle-tested for 15+ years.
  • Microsoft Word collaborative: hybrid OT-like.
  • Figma: in-house CRDT-like, optimized for vector graphics; documented design talks.
  • Notion: CRDT-based for blocks; uses Yjs internally for some surfaces.
  • Linear, Excalidraw: CRDT (Yjs).
  • Replit's multiplayer: CRDT-based for code collaboration.