The Problem: Two People Typing in the Same Sentence

Asha and Ravi open the same Google Doc. At the same instant, Asha types "Hello " at the start, and Ravi deletes a word in the middle. Both changes travel over the internet, arriving at different times. Yet both screens end up showing exactly the same document, and nobody's work is lost.

That's the core of designing Google Docs: real-time collaborative editing with conflict resolution. Google Docs uses a technique called operational transformation (OT). This post explains it with diagrams.


๐ŸŽฏ Quick Answer (30-Second Read)

  • Every edit is an operation, like "insert 'H' at position 5" or "delete 3 characters at position 10."
  • Each client applies its own edits instantly, then sends them to a central server.
  • The server orders all operations for a document and transforms concurrent ones so they still make sense.
  • Transformed operations are broadcast, so every client converges to the same text.
  • Extras: live cursors (presence), revision history built from the operation log, and offline edits replayed on reconnect.

Why Naive Syncing Breaks

Document: CAT

sequenceDiagram participant A as Asha participant B as Ravi Note over A,B: Both start with "CAT" A->>A: insert "S" at 0 โ†’ "SCAT" B->>B: delete at 2 ("T") โ†’ "CA" A->>B: insert "S" at 0 B->>B: "SCA" โœ“ B->>A: delete at 2 A->>A: deletes "A" โ†’ "SCT" โŒ Note over A,B: Screens disagree: "SCA" vs "SCT"

Ravi's "delete position 2" was based on the old text. After Asha's insert, the "T" moved to position 3. Applying the operation unchanged deletes the wrong letter.


Operational Transformation Fixes It

OT adjusts an incoming operation for any concurrent operations that were applied first:

  • Ravi's delete at 2 arrives after Asha's insert at 0.
  • Asha's insert was before position 2, so shift Ravi's delete by one: delete at 3.
  • Applying it to "SCAT" deletes "T" โ†’ "SCA" on both screens. โœ…
flowchart LR OP["Incoming op:
delete at 2"] --> T{"Transform against
concurrent ops"} C["Already applied:
insert 'S' at 0"] --> T T --> OUT["Adjusted op:
delete at 3"]

High-Level Architecture

flowchart TB A["๐Ÿ–ฅ๏ธ Editor A"] <-->|"WebSocket / long-lived connection"| S B["๐Ÿ–ฅ๏ธ Editor B"] <--> S C["๐Ÿ“ฑ Viewer C"] <--> S S["Collaboration server
per-document ordering +
operational transformation"] --> LOG[("Operation log
(revision history)")] S --> SNAP[("Document snapshots")] S --> PRES["Presence service
cursors, who's online"] API["Docs API, sharing,
permissions"] --> ACL[("Access control")]
Component Job
Collaboration server Owns the authoritative order of operations for a document
Operation log Every change ever made; powers version history and recovery
Snapshots Periodic full copies so loading a doc doesn't replay its entire history
Presence Shows cursors and selections, which are frequent but disposable updates
Access control Who can view, comment or edit

The Client-Server Flow

  1. You type. Your editor applies the change immediately (no waiting for the server).
  2. It sends the operation, tagged with the revision it was based on.
  3. The server transforms it against any operations it has accepted since that revision, appends it to the log, and assigns a new revision number.
  4. The server acknowledges you and broadcasts the transformed operation to everyone else.
  5. Each client transforms incoming operations against its own unacknowledged local edits, so its view stays consistent.
Key takeaway: a single server deciding the order of operations for each document makes OT manageable. Google described this client-server approach (based on the Jupiter collaboration system) when it rebuilt Docs' collaboration in 2010.

OT vs CRDT

Operational Transformation CRDTs
Idea Transform operations against each other Data structures that merge automatically
Needs a central server? Usually yes, for ordering No, works peer-to-peer
Used by Google Docs Many newer tools and libraries (e.g. Yjs, Automerge)
Offline / P2P Harder Strong fit

Figma took a middle path: CRDT-inspired with a central server (How Figma's Multiplayer Works).


Extras Interviewers Like

  • Revision history: replay or snapshot the operation log to show any past version
  • Offline editing: queue local operations and transform them against the server's when reconnecting
  • Presence throttling: send cursor positions at a limited rate; they don't need to be stored
  • Large documents: load snapshots, paginate, lazy-load images
  • Permissions: check edit rights on every operation, not just on page load

Frequently Asked Questions

How does Google Docs handle simultaneous edits?

Google Docs uses operational transformation. Each edit is an operation sent to a central server, which orders operations for the document and transforms concurrent ones so their positions stay correct. The server broadcasts the transformed operations, and all clients converge to the same document.

Does Google Docs use CRDT or OT?

Google Docs uses operational transformation with a central server, an approach Google described when it relaunched Docs' real-time collaboration in 2010. CRDTs are an alternative used by many newer collaboration tools, especially for offline and peer-to-peer editing.

How would you design Google Docs in an interview?

Describe operations as the unit of change, optimistic local application, a per-document server that orders and transforms operations, broadcasting over persistent connections, an operation log with snapshots for history, a presence service for cursors, and access control checked on every edit.


Conclusion

Google Docs works by turning every keystroke into an operation, applying it locally right away, and letting a central server order and transform concurrent operations so every copy converges. An operation log gives version history for free, and a lightweight presence system adds live cursors.


Sources

Last verified: 2 November 2026.


Related reads: How Figma's Multiplayer Works ยท WebSocket vs SSE ยท CAP Theorem Explained ยท Write-Ahead Log Explained

I write about system design and how real products are built. Follow on LinkedIn or X, or invite me to speak.