System Design: Real-time Collaborative Text Editor (Google Docs / Notion)
This comprehensive study note covers the High-Level Design (HLD) and Low-Level Design (LLD) for a real-time collaborative text editor like Google Docs or Notion. The system enables multiple users to simultaneously create, modify, and delete documents, view real-time changes and peer cursor positions, and manage document versioning.
1. Why Do We Need This? (Problem Statement & Status Quo)
Modern knowledge work demands asynchronous and synchronous collaboration. Traditional single-user text editors require locking files or emailing revisions back and forth, leading to split-brain states and lost updates.
Building a real-in-time collaborative editor introduces unique distributed systems challenges:
- Concurrent Edits: Multiple users modify the exact same sentence or paragraph at the exact same millisecond.
- Network Latency & Reliability: Users connect via unstable mobile or desktop networks with varying latencies.
- Massive Scale: Millions of active users concurrently editing billions of documents.
2. Core Mental Model & Real-Life Analogy
Real-Life Analogy: The Shared Physical Chalkboard vs. Google Docs
Imagine multiple authors writing a book simultaneously:
- Naive Approach (Passing the Notebook): Author A writes a paragraph, hands the physical notebook to Author B, who overwrites or appends. Nobody else can write while one holds it.
- Collaborative Approach (Google Docs): Every author has their own notepad copy. Whenever they write a word, they shout out the exact delta change (e.g., "Insert letter 'R' at character index 29"). A central editor (or algorithm) harmonizes these shouts so everyone's notepad matches identically.
3. Functional and Non-Functional Requirements
Functional Requirements
- Document CRUD: Users can create, view, modify, and delete documents.
- Real-time Collaboration: Single or multiple users can edit documents simultaneously.
- Near Real-time Propagation: Changes made by User A reflect on User B's screen instantly.
- Presence & Cursors: Users can see active collaborators and their live cursor/selection positions.
- File Versioning: The backend maintains historical snapshots and versions (similar to Confluence/Google Docs version history).
Non-Functional Requirements
- Scale: Support millions of concurrent active users and billions of stored documents.
- CAP Theorem Trade-off:
- Offline / Solo Editing: High Availability (AP system with eventual consistency).
- Collaborative Live Editing: High Consistency (CP preference; real-time conflict resolution is mandatory).
- Latency: Sub-100 millisecond round-trip latency for edit propagation between peers.
4. Core Entities & Database Schema Design
Based on our functional requirements, we identify four primary core entities: User, Document, Edit (Operation), and Cursor.
Database Architecture & Tables
1. Document Metadata Database (Cassandra / PostgreSQL)
Stores high-level attributes for documents. Because writes are heavy, we use a write-heavy distributed store like Apache Cassandra backed by a Kafka ingestion buffer.
2. Operation Database (Event Store)
Logs granular character-level delta changes for replay and reconciliation.
3. Version History Table
Stores historical snapshots of documents taken during auto-saves or manual commits.
5. API Design & Communication Protocols
REST API Endpoints (Metadata & Document Management)
- Create Document:
POST /api/v1/documents-> Returns{ document_id } - View Document (Read-Only):
GET /api/v1/documents/{document_id}-> Returns document payload - Delete Document:
DELETE /api/v1/documents/{document_id} - Fetch Document Versions:
GET /api/v1/documents/{document_id}/versions - Fetch Specific Version:
GET /api/v1/documents/{document_id}/versions/{version_id}
WebSocket Protocol (Real-time Editing)
For real-time bidirectional streaming of edits, we bypass standard HTTP request-response REST endpoints in favor of persistent WebSockets.
- Connection URL:
wss://editor.playbooklibrary.com/ws/document/{document_id} - Payload Structure (Client -> Server):
JSON
{ "action": "EDIT", "documentId": "doc_123", "userId": "user_456", "operation": { "type": "INSERT", "position": 29, "char": "R" }, "cursor": { "line": 2, "offset": 14 } }
6. High-Level System Architecture
The high-level architecture separates HTTP traffic (metadata and static file reads) from real-time WebSocket traffic (collaborative text editing).
7. Evolution of Collaborative Editing Approaches
To understand why advanced algorithms are required, let's examine three architectural evolutions:
Approach 1: File Replacement (Naive Brute Force)
- Mechanism: Every single keystroke transmits the entire document file via HTTP to the backend, which overwrites storage and broadcasts an update via Server-Sent Events (SSE) to all peers.
- Why it fails: Payload sizes are massive. Generating thousands of full-file write requests per second exhausts network bandwidth and database IOPS instantly.
Approach 2: Locking Protocols (Pessimistic / Optimistic)
- Mechanism: User A locks the document (or paragraph) while editing. User B must wait until User A releases the lock.
- Why it fails: Destroys the core premise of real-time collaboration. Users cannot work concurrently.
Approach 3: Delta Transformation (The Modern Solution)
- Mechanism: Clients transmit only the delta (e.g., "Insert 'R' at index 29") over a persistent WebSocket connection, rather than the whole file.
- The Conflict Problem: If Alice inserts 'A' at index 0 and Bob inserts 'D' at index 2 simultaneously, naive merging results in divergent client states (Alice sees
ABDC, Bob seesABCD). We need conflict reconciliation algorithms.
8. Conflict Resolution Algorithms: OT vs. CRDT
To reconcile concurrent edits across distributed clients, two primary mathematical frameworks exist:
Google Docs specifically relies on Operational Transformation (OT), where transformations happen on both the client side and the backend server.
9. Low-Level Design (LLD): Deep Dive into the Editor Service
Let's trace the deep-dive architecture of our Low-Level Design for real-time editing.
Component Breakdown & Data Flows
-
Session Initialization:
- User opens a document via REST. The API Gateway fetches the latest snapshot from S3 Blob Storage (accelerated via a CDN).
- User initiates a WebSocket connection for editing. The connection hits the WebSocket Load Balancer, which routes stickily to a specific node in the Document Editor Service Cluster.
-
In-Memory Canonical State (Redis):
- To avoid hitting S3 or SQL on every keystroke, the Document Editor Service maintains the active canonical state of the document in a Redis Cluster.
- Cursors and presence states are also stored in Redis with a short Time-To-Live (TTL). If a user disconnects abruptly, their cursor automatically expires.
-
Asynchronous Durability (Kafka & Operation DB):
- When edits stream in via WebSocket, the Editor Service writes the raw delta event to a Kafka Queue for durability and audit trails.
- An Operation Consumer Service flushes these events from Kafka into the persistent Operation DB.
-
Snapshot Versioning & Background Reconciliation:
- Every 10 to 20 seconds (or on manual save), an auto-save routine creates a snapshot version of the document, writing it to S3 Blob Storage and recording an entry in the Version History Table.
- Reconciliation Job: A background worker runs periodically after edit sessions end. It reads intermediate minor event logs from the Operation DB, applies them against the base snapshot using OT, generates a clean consolidated major version (e.g.,
10.1), persists it to S3, and purges transient minor events to reclaim storage.
10. Summary and Key Takeaways
- Functional Simplicity, Distributed Complexity: While user-facing requirements are straightforward CRUD and real-time viewing, the underlying engine requires sophisticated concurrency control.
- WebSocket over HTTP: Real-time collaborative text editing demands persistent, bidirectional duplex connections rather than standard REST/HTTP requests.
- Delta Transmission: Never transmit full files on keystrokes; send compact operational deltas (
insert,delete,index). - Operational Transformation (OT): Google Docs relies on OT to transform concurrent user operations against each other, ensuring uniform document state across all clients.
- Centralized Canonical State: Using an in-memory Redis cluster maintains fast read/write speeds for active editing sessions, while Kafka buffers high-throughput write streams.
- Asynchronous Snapshotting: Periodic auto-saves and background reconciliation jobs compress minor operational deltas into clean major version snapshots in S3 blob storage.