Capabilities/Collaboration & UX

Collaborative Real-Time Editing

CRDTs vs Operational Transform for conflict-free concurrent document editing

CRDTOTcollaborationreal-timeconflict-resolution

Learning lens

Start with judgment, not a universal prescription.

This page is a learning model for understanding the capability. It does not claim exact production internals, exact costs, or an infinite-scale architecture.

Evidence

Conceptual pattern

0->1 default

Start with a collaboration model that matches the product promise; do not choose CRDTs or OT before conflict behavior is clear.

Cost drivers

sync trafficdocument historypresence updatesconflict resolution complexity

Watch for breakpoints

  • -offline edits become common
  • -conflicts create support load
  • -large documents slow sync or replay

Learn first

Concepts behind this architecture

The Problem

Google Docs, Figma, and Notion allow multiple users to edit the same document simultaneously without conflicts. This requires solving one of the hardest problems in distributed systems: concurrent edits on shared state. When Alice inserts “hello” at position 5 while Bob deletes character 3, both operations must be applied on both clients to produce the same final document — regardless of the order they arrive. The system must handle network latency, offline edits, cursor/selection tracking, and undo/redo, all while feeling instantaneous to each user.

Architectural Approaches

Operational Transform (OT)

Each edit is represented as an operation (insert, delete, retain). When concurrent operations arrive, a transform function adjusts their positions so they can be applied in any order and produce the same result. The server acts as a central authority that orders operations. Used by Google Docs.

Pros

  • +Well-understood — decades of research and production use
  • +Compact operations — efficient over the network
  • +Central server simplifies conflict resolution
  • +Good support for rich text (formatting, embeds)

Cons

  • −Transform functions are notoriously hard to get right
  • −Requires a central server for operation ordering
  • −Doesn't work well offline or in peer-to-peer scenarios
  • −Complexity explodes with rich document types (tables, nested structures)

Conflict-Free Replicated Data Types (CRDTs)

CRDTs are data structures that can be modified independently on multiple replicas and always converge to the same state when merged — without coordination. Each character/element has a unique ID that determines its position, making concurrent inserts/deletes naturally commutative. No central server needed.

Pros

  • +Mathematically guaranteed convergence — no conflicts by design
  • +Works offline — edits merge cleanly when reconnected
  • +No central server required — supports peer-to-peer
  • +Simpler mental model — just merge states, no transform functions

Cons

  • −Higher memory overhead — each character needs a unique ID and metadata
  • −Document tombstones accumulate (deleted elements are marked, not removed)
  • −Garbage collection of tombstones requires coordination
  • −Fewer production-proven implementations than OT

Hybrid: CRDT with Server Authority

Use a CRDT for conflict resolution but route all operations through a central server for ordering, persistence, and access control. Combines CRDT’s convergence guarantees with server-side features (undo history, permissions, search indexing). This is the approach used by Figma and increasingly by modern editors.

Pros

  • +CRDT convergence with server-side features
  • +Server provides canonical ordering and persistence
  • +Offline edits merge cleanly via CRDT
  • +Server can enforce permissions and validate operations

Cons

  • −Complexity of both CRDT and server coordination
  • −Must handle divergence between optimistic local state and server state
  • −CRDT metadata overhead still applies
  • −Server becomes a dependency (though offline mode is possible)

Architecture

Loading diagram...
Collaborative Real-Time Editing — High-level architecture

Key Components

CRDT/OT Engine

Core algorithm that handles concurrent edit merging. For CRDTs: Yjs, Automerge, or Diamond Types. For OT: ShareDB or custom implementation. Runs on both client (for local application) and server (for canonical state). Must handle all document operations: insert, delete, format, move.

WebSocket Sync Layer

Bidirectional real-time connection for exchanging operations between clients and server. Clients send local operations immediately for low-latency feel. Server broadcasts operations to all connected clients. Handles reconnection with state sync (send missed operations or full document state).

Cursor & Presence Tracker

Tracks each user’s cursor position, text selection, and active status. Broadcasts cursor updates to all clients for collaborative awareness (colored cursors with user names). Cursor positions must be transformed when concurrent edits shift text positions.

Document Store

Persists the canonical document state. For CRDTs, stores the serialized CRDT state (or operation log that can rebuild it). For OT, stores the document state plus the operation history. Periodic snapshots reduce the cost of loading documents (don’t need to replay entire history).

Version History

Stores named snapshots and the complete operation log. Enables “version history” UI (view/restore past versions). For CRDTs, each snapshot is a serialized CRDT state. Operation log enables granular undo per user (undo only my operations, not others’).

Permission Service

Controls who can view, edit, or comment on each document. Checks permissions on every incoming operation. Must handle real-time permission changes (revoke access while user is editing — disconnect their WebSocket and discard pending operations).

Data Model

Loading diagram...
Collaborative Real-Time Editing — Entity relationship diagram

How CRDTs Work for Text

Text CRDTs assign each character a unique, globally ordered ID that determines its position in the document, independent of array indexes.

Yjs approach (YATA algorithm):

  • Each character has an ID: (clientID, clock) — e.g., (Alice, 5)
  • Each character knows its left neighbor’s ID
  • When inserting between two characters, the new character’s position is determined by its left neighbor, making concurrent inserts at the same position deterministic
  • Deletes mark characters as tombstones (logically deleted but still in the structure)

Example of concurrent edits:

  • Document: “AC”
  • Alice inserts “B” between A and C → “ABC”
  • Bob inserts “X” between A and C → “AXC” (concurrently)
  • When both operations are merged, the CRDT determines a consistent ordering: “ABXC” or “AXBC” — the same on both clients, determined by the character IDs

Why it always converges: The unique IDs and ordering rules are commutative — applying Alice’s edit then Bob’s produces the same result as applying Bob’s then Alice’s. This is the mathematical guarantee of CRDTs.

Libraries:

  • Yjs: Most popular, small bundle (15KB), supports ProseMirror, CodeMirror, Monaco, Tiptap
  • Automerge: Research-quality, supports JSON documents, Rust core with WASM bindings
  • Diamond Types: Rust-based, extremely memory-efficient, designed for performance

Awareness and Cursor Synchronization

Seeing other users’ cursors and selections is essential for the collaborative experience.

Awareness protocol (Yjs):

  • Each client broadcasts its “awareness state”: cursor position, selection range, user name, user color
  • Updates sent via WebSocket alongside document operations
  • Awareness states have a 30-second timeout — if not refreshed, the user is considered disconnected

Cursor position challenges:

  • Cursor positions are indexes into the document. When another user inserts text before your cursor, your cursor position must shift.
  • For OT: transform cursor positions using the same transform functions as text operations
  • For CRDTs: store cursor position as a reference to a character ID (not an index). The cursor “follows” the character regardless of insertions/deletions around it.

Visual design:

  • Each user gets a distinct color (from a predefined palette)
  • Show a thin vertical line (caret) at their cursor position
  • Show a colored highlight for their selection range
  • Display the user’s name in a small label above the cursor
  • Fade out cursors of idle users (no activity for 60 seconds)

Performance: Don’t send cursor updates on every keystroke. Throttle to 50-100ms intervals. Use a separate “awareness” channel that’s lower priority than document operations.

Offline Editing and Conflict Resolution

True offline support is a key advantage of CRDTs over OT.

Offline workflow:

  1. User edits the document while disconnected. All operations are applied to the local CRDT replica.
  2. On reconnection, the client sends its accumulated operations to the server.
  3. The server merges the operations with any changes made by other users during the disconnection.
  4. The server sends back any operations the offline client missed.
  5. Both sides converge to the same state — guaranteed by the CRDT.

No conflicts: Unlike traditional merge (Git-style with conflict markers), CRDTs never produce conflicts. Concurrent edits to the same paragraph always merge deterministically. The result may not be what either user intended (if they edited the same sentence), but it’s always a valid document state.

Long offline periods: If a user is offline for days, the merge may produce unexpected results. Consider showing a “merge preview” UI that highlights what changed while they were away, similar to a diff view.

OT limitations: Traditional OT requires a central server to order operations. Offline OT is possible (Google Docs buffers operations and sends on reconnect) but requires the server to be available to reconcile. Extended offline editing with OT is fragile.

Storage: Offline clients must store their local CRDT state and pending operations in IndexedDB or SQLite. On reconnection, sync the pending operations first, then verify convergence by comparing document checksums.

Real-World Examples

Google Docs

Uses Operational Transform with a central server. Each keystroke generates an operation sent to Google’s servers, which transform and broadcast to other clients. The server maintains the canonical document state. Supports offline editing by buffering operations.

Figma

Custom CRDT implementation for the design canvas. Each object on the canvas is a CRDT with properties that can be independently modified. Server acts as a relay and persistence layer. Handles complex operations like moving objects between frames.

Notion

Block-based document model with OT-inspired sync. Each block (paragraph, heading, list item) is independently editable. Operations are block-level (insert block, update block content, move block). Server maintains block ordering and content.

Linear

Uses CRDTs (Automerge-inspired) for offline-first issue tracking. All issue fields are CRDT properties that merge on sync. Supports full offline mode — create, edit, and comment on issues without connectivity. Syncs when back online.

Architectural Tradeoffs

OT vs CRDT for text collaboration

Pros

  • +OT: compact operations, lower memory overhead
  • +CRDT: guaranteed convergence, works offline/peer-to-peer
  • +OT: more mature for rich text (decades of research)

Cons

  • −OT: transform functions are error-prone, needs central server
  • −CRDT: higher memory (unique IDs per character), tombstone accumulation
  • −CRDT: fewer production-proven rich text implementations

Server-authoritative vs peer-to-peer sync

Pros

  • +Server: central persistence, access control, easier debugging
  • +P2P: works without server, lower latency between nearby peers
  • +Server: canonical state for search indexing and version history

Cons

  • −Server: single point of failure, added latency hop
  • −P2P: complex NAT traversal, no central authority for permissions
  • −P2P: harder to implement version history and admin features

Character-level vs block-level sync

Pros

  • +Character: finest granularity, best for text-heavy editing
  • +Block: simpler, fewer operations, natural for structured documents
  • +Character: handles concurrent edits within the same paragraph

Cons

  • −Character: more operations, higher bandwidth and processing
  • −Block: concurrent edits to the same block can conflict
  • −Block: less smooth for pure text editing (entire block replaced)

Learn Collaborative Real-Time Editing

Copy a learning context prompt for an AI assistant. It keeps assumptions visible and asks for tradeoffs, cost drivers, failure modes, and what to measure before adding complexity.

Explore More Capabilities