RoadmapDay 48 / 80
System DesignMonth 3 · Week 10

Day 48: Design: Collaborative Document Editor (Google Docs/Figma)

Understand the two dominant conflict-resolution models for real-time collaborative editing — Operational Transformation and CRDTs — and their tradeoffs.

Mark this day complete

Study

Concepts

The core problem: concurrent edits to the same document

Two users type in the same paragraph at the same time. Without a resolution strategy, applying both edits naively (e.g. by raw text-insert-at-index) corrupts the document, because the second edit's index was computed against a document state that no longer exists once the first edit is applied. Real-time collaborative editors need a way to transform or merge concurrent operations so every client converges to the SAME final document, regardless of the order operations arrive in.

Operational Transformation (OT) — used historically by Google Docs — transforms an incoming remote operation against any local operations that happened concurrently, adjusting its index/position so it applies correctly on top of local changes; it requires a central server to serialize and broadcast a canonical operation order, and the transform functions are notoriously tricky to get exactly right for complex operations.

CRDTs: convergence without a central authority

A CRDT (Conflict-free Replicated Data Type) is a data structure specifically designed so that ANY set of concurrent operations, applied in ANY order, on ANY replica, converges to the same final state — mathematically, by construction, without needing a central server to decide ordering. For text editing, this typically means each character (or block) gets a unique, ordered identifier (e.g. via a technique like RGA or Logoot) so insertions/deletions can be applied locally and merged from any peer without conflicts, enabling true peer-to-peer or offline-then-sync collaborative editing (Yjs and Automerge are the dominant real-world CRDT libraries).

The practical tradeoff: OT is generally more compact on the wire and mature in battle-tested systems, but is server-dependent and hard to implement correctly from scratch; CRDTs are more resilient to offline/peer-to-peer scenarios and easier to reason about correctness-wise, but historically carried more memory/metadata overhead per character (modern CRDT libraries like Yjs have optimized this substantially).

See It

Visualizations

Visualization

Operational Transformation vs CRDTs

 OTCRDT
Requires central serverYes — to serialize operation orderNo — convergence by construction
Works offline / peer-to-peerPoorly — needs server round trip to transformNaturally — merge whenever peers reconnect
Implementation difficultyHigh — transform functions are notoriously trickyModerate — but subtle correctness details still matter
Real-world examplesGoogle Docs (historically)Figma (custom CRDT-like), Yjs, Automerge
Per-character overheadLowHistorically higher, much improved in modern libs

Visualization

A CRDT-based editor architecture (Yjs-style)

Client Alocal Yjs doc, edits applied instantly
Sync ProviderWebSocket/WebRTC relay of CRDT updates
Client Blocal Yjs doc, merges remote updates

Build It

Code Examples

A minimal collaborative text editor with Yjs

jsx
import * as Y from 'yjs';
import { WebsocketProvider } from 'y-websocket';

const ydoc = new Y.Doc();
const provider = new WebsocketProvider('wss://sync.example.com', 'doc-room-1', ydoc);
const ytext = ydoc.getText('content'); // a CRDT-backed shared text type

function CollaborativeEditor() {
  const [text, setText] = useState(ytext.toString());

  useEffect(() => {
    const observer = () => setText(ytext.toString()); // fires on ANY remote or local change
    ytext.observe(observer);
    return () => ytext.unobserve(observer);
  }, []);

  function handleChange(e) {
    const newValue = e.target.value;
    // Applying a diff (not a full replace) lets Yjs merge this
    // correctly against concurrent remote edits automatically.
    ydoc.transact(() => {
      ytext.delete(0, ytext.length);
      ytext.insert(0, newValue);
    });
  }

  return <textarea value={text} onChange={handleChange} />;
}
// Two browser tabs pointed at the same room converge automatically —
// no server-side transform logic required, and it survives brief disconnects.

Remember

Key Takeaways

  • Naive concurrent text edits corrupt a document — real-time collaboration requires OT or CRDTs to guarantee convergence.
  • OT transforms incoming operations against concurrent local ones; it requires a central server to establish a canonical order.
  • CRDTs are data structures designed so ANY merge order converges to the same state — no central authority required.
  • CRDTs handle offline-then-reconnect and peer-to-peer scenarios far more naturally than OT.
  • Yjs and Automerge are the production-grade CRDT libraries most teams should reach for rather than implementing OT/CRDT from scratch.

Do It

Practice

  1. 1Build the two-tab Yjs demo above and prove convergence by editing simultaneously in both tabs while briefly disabling network in one.
  2. 2Explain in your own words why naive "insert at index N" breaks under concurrent edits, with a concrete two-user example.
  3. 3Research and summarize (2-3 sentences) how Figma's multiplayer technology differs from a textbook CRDT for text.