Skip to content

CONCEPT Cited by 2 sources

Operational Transform (OT)

Operational Transform (OT) is the dominant real-time-collaboration algorithm of the Google-Docs / Etherpad / pre-2015 era. It represents edits as operations (typically insert(offset, char), delete(offset)) and — when two concurrent operations arrive — it transforms each operation against the other so the server and each client converge on the same final state despite applying operations in different orders.

Example: client A types "X" at offset 5. Before A's op reaches the server, client B deletes offset 3. When B's op reaches A, A must adjust its pending "insert at 5" to "insert at 4" (because the earlier delete shifted everything right of offset 3 left by one). Formally, the transform is a function (op_A, op_B) → (op_A', op_B') such that apply(apply(s, op_A), op_B') == apply(apply(s, op_B), op_A') — i.e., operations commute after transformation.

Why Figma rejected it

Figma's 2019 multiplayer design explicitly evaluated and rejected OT (Source: sources/2019-figma-how-figmas-multiplayer-technology-works):

  • "Unnecessarily complex for our problem space." OT was built for linear text, where operations have natural integer-offset keys. Figma documents are trees of graphics objects with properties — no natural linear-offset primitive.
  • Combinatorial-state-explosion critique. Figma cites Li & Li ("formal proofs are very complicated and error-prone, even for OT algorithms that only treat two characterwise primitives"). See Wikipedia's critique of OT. The number of (op_A, op_B) transform cases grows super-linearly with the primitive set; proving transform functions commute requires exhaustive case analysis that scales badly.
  • Overkill on memory/perf. OT's payoff is low per-op memory + serial log. Figma's per-document-process server architecture doesn't need OT's efficiency tricks — it can afford a CRDT-style state-based reconciliation.

Figma chose CRDT-inspired centralized reconciliation instead.

When OT still wins

  • Long linear text with frequent character-level edits (Google Docs, collaborative code editors).
  • Workloads that need the per-op serial log as the authoritative representation (for operational replay, undo stacks, audit).
  • Where per-op memory footprint dominates (CRDT metadata per operation can be multiple times the op itself).

Seen in

  • sources/2019-figma-how-figmas-multiplayer-technology-works — Figma's explicit rejection of OT, with the state-explosion critique quoted.
  • sources/2025-06-02-mongodb-conformance-checking-at-mongodb-testing-that-our-code-matches-our-tla-specs — MongoDB's Mobile SDK (sunset as Atlas Device Sync) used OT across C++ client + Go server implementations. The server's 2020 rewrite-to-Go created two OT impls with conformance risk; test-case generation from a 2-week-old TLA+ spec of the ~1000-line array-merge portion (19 op types / 6 array ops / 21 merge rules) produced 4,913 tests with 100% branch coverage and found a real infinite-recursion bug on swap+move conflict (TLC crashed with Java StackOverflowError) that handwritten tests + AFL fuzzer had missed. The combinatorial-state-explosion critique Figma quoted is exactly what this was: 21 merge rules for 6 array ops is the kind of growth Li & Li warned about — and what made exhaustive test-case generation tractable only at tight state-space constraints (3×3×1).
Last updated · 200 distilled / 1,178 read