Design a Collaborative Editor — Real-Time Sync Like Google Docs
The hardest real-time problem#
Building a collaborative editor where multiple users type simultaneously without losing changes or seeing glitches is one of the hardest distributed systems problems.
Google Docs, Notion, and Figma each solve it differently. Understanding the approaches teaches you real-time sync, conflict resolution, and distributed state management.
The fundamental challenge#
Two users type at the same position simultaneously:
Document: "Hello World"
User A: Insert "X" at position 5 → "HelloX World"
User B: Insert "Y" at position 5 → "HelloY World"
Both operations arrive at the server.
What should the final document be?
"HelloXY World"? "HelloYX World"?
Both users must see the same result.
Approach 1: Operational Transformation (OT)#
Used by Google Docs. Transform operations against each other so they produce the same result regardless of order.
How it works:
- Each edit is an operation:
Insert("X", pos=5)orDelete(pos=3) - When two operations conflict, transform one against the other
- Transform adjusts positions to account for the other operation
Example:
User A: Insert("X", 5)
User B: Insert("Y", 5)
Transform B against A:
B was at position 5, but A inserted before it
B becomes: Insert("Y", 6)
Result: "HelloXY World" (deterministic)
Pros: Well-understood, proven at Google scale Cons: Complex transformation rules, centralized server required, hard to implement correctly
Approach 2: CRDTs (Conflict-Free Replicated Data Types)#
Used by Figma, Notion (partially), and Yjs. Data structures that can be merged without conflicts by design.
How it works:
- Each character has a unique ID (user + logical timestamp)
- Characters are ordered by their IDs, not positions
- Insertions place new characters between existing ones
- Deletions mark characters as tombstones (not removed)
Popular CRDT libraries:
- Yjs — Most popular, supports text, arrays, maps
- Automerge — Rust-based, good for structured data
- Diamond Types — Optimized for text editing
Pros: No central server needed, works offline, peer-to-peer capable Cons: Tombstones accumulate (memory), eventual consistency only
Architecture#
Server-side (OT approach)#
Client A → WebSocket → Server (single source of truth)
Client B → WebSocket ↗ ↓ transform + broadcast
Client C → WebSocket ↗ ↓
All clients get transformed operations
Peer-to-peer (CRDT approach)#
Client A ←→ Sync Server ←→ Client B
←→ ←→ Client C
Each client has full document state
Server relays, doesn't transform
Cursor presence#
Showing where other users are typing:
- Each client sends cursor position updates (throttled to 50ms)
- Server broadcasts cursor positions to all other clients
- Client renders colored cursors with user name labels
Optimization: Don't send cursor updates on every keystroke — throttle or debounce, and batch with document operations.
Key components#
Document model: Tree of blocks (paragraphs, headings, lists) containing text runs with formatting.
Operation log: Append-only log of all operations for undo/redo and time travel.
Version vector: Track which operations each client has seen to detect gaps.
Awareness protocol: Cursor positions, selections, user online status.
Persistence: Periodically snapshot the document state to avoid replaying the entire operation history on load.
Scaling considerations#
| Challenge | Solution |
|---|---|
| WebSocket connections | Horizontal scaling with sticky sessions or shared state |
| Large documents | Lazy load blocks, only sync visible sections |
| Operation history growth | Periodic snapshots, garbage collect old ops |
| Offline editing | CRDT enables full offline support, sync on reconnect |
| Permission changes | Real-time permission checks on each operation |
Visualize your collaborative editor#
See how real-time sync, WebSockets, and document storage connect — try Codelit to generate an interactive diagram of a collaborative editor.
Key takeaways#
- OT is proven at scale (Google Docs) but requires a central server
- CRDTs enable offline + peer-to-peer but use more memory
- Cursor presence needs throttled WebSocket updates
- Yjs is the go-to CRDT library for most use cases
- Snapshot periodically to avoid replaying entire history
- Both approaches converge — the document ends up the same regardless of operation order
Try it on Codelit
Chaos Mode
Simulate node failures and watch cascading impact across your architecture
90+ Templates
Practice with real-world architectures — Uber, Netflix, Slack, and more
Related articles
Try these templates
Uber Real-Time Location System
Handles 5M+ GPS pings per second using H3 hexagonal geospatial indexing.
6 componentsInstagram-like Photo Sharing Platform
Full-stack social media platform with image processing, feeds, and real-time notifications.
12 componentsReal-Time Collaborative Editor
Notion-like document editor with real-time collaboration, conflict resolution, and rich media.
9 componentsBuild this architecture
Generate an interactive architecture for Design a Collaborative Editor in seconds.
Try it in Codelit →
Comments