Google Docs System Design Interview: Real-Time Collaborative Editing
Google Workspace crossed 3 billion users (Google, 2023), and Docs is one of its most used apps. The hard requirement is that when one person types, everyone else editing the same document sees the change in well under a second. A common design target for that change-propagation is under 100 to 200 ms of perceived sync latency (estimate, based on published real-time collaboration goals rather than an official Docs SLA).
Google Docs lets many people edit the same document at the same time and each person sees the others' keystrokes almost instantly. The core problem is not storage, it is conflict resolution: two edits that happen concurrently must be merged so every client converges on the exact same final text. Google solves this with Operational Transformation, where each edit is a small operation that gets transformed against operations it did not know about. A single collaboration server per document gives every operation a total order, which is what makes convergence tractable. On top of that sit presence, remote cursors, offline editing with later reconciliation, comments, sharing permissions, and a version history built from the operation log.
Asked at: Google, Microsoft, Atlassian, Notion, Figma, Dropbox, and most companies that build collaborative editors or shared canvases.
Why this question is asked
This question is popular because it forces you off the standard CRUD path and into distributed concurrency. There is no correct answer that avoids the central issue: if two users edit the same region of a document at the same moment, what does the final state look like, and how do you guarantee that every participant computes the identical result. A strong candidate has to reason about operation ordering, transformation of concurrent edits, low-latency fan-out over persistent connections, presence and remote cursor rendering, offline edits that reconnect and reconcile against a document that moved on without them, and how to store enough history to rebuild any past version. It rewards depth on Operational Transformation or CRDTs and punishes hand-waving.
Requirements
Always clarify these in the first 5 minutes of the interview. Do not start drawing boxes until both lists are agreed.
Functional requirements
- Multiple users can open and edit the same document at the same time.
- Each user sees other users' edits appear in near real time, character by character.
- Each user sees other participants' cursors and text selections, labeled by person.
- Concurrent edits to the same document converge so every client ends with identical content.
- Users can edit offline and have their changes reconciled with the server on reconnect.
- Users can add comments and suggested edits anchored to specific text ranges.
- The system keeps version history so a user can view or restore an earlier state.
- Documents can be shared with view, comment, or edit permissions per user or link.
- Rich text formatting (bold, headings, lists, tables) is preserved across concurrent edits.
Non-functional requirements
- Change-propagation latency should feel instant, a target of under 100 to 200 ms perceived sync (estimate).
- High availability, since a document that will not open blocks the user's work entirely.
- Durability: no acknowledged edit may ever be lost, even across server restarts.
- Convergence consistency: all clients of one document must reach byte-identical final state.
- The connection layer must scale to many concurrent editors and idle viewers per document.
- Offline reconciliation must be deterministic and must not silently drop a user's work.
- Version history must be reconstructable at low cost from stored operations and snapshots.
Back-of-envelope scale estimates
Show your math. Pulling numbers from thin air signals you have not thought about the load.
Total users
3B+ Workspace users
Google reported 3 billion Workspace users in 2023. Docs is a subset of active users but the addressable base is this large.
Documents stored
tens of billions (estimate)
Derived. With billions of users each owning tens to hundreds of documents over years, total document count reaches tens of billions. No official figure is published.
Concurrent editors per doc
typically 1 to 20, capped near 100 active editors (estimate)
Most docs have one editor at a time. Heavily collaborated docs reach dozens. Google historically limited simultaneous editing to around 100 users, which is a reasonable design ceiling.
Edits per second (busy doc)
50 to 200 ops/sec (estimate)
Derived. Each keystroke, cursor move, and formatting change is an operation. A dozen fast typists produce roughly this range during active editing.
Operation size
tens to hundreds of bytes per op (estimate)
Derived. A single insert or delete plus position, author id, and revision metadata is small. Operation logs are cheap to store relative to media.
Snapshot cadence
every N operations or minutes (design choice)
Snapshots bound replay cost. Compacting the op log into a materialized document state every few hundred operations keeps document open time fast.
High-level architecture
A client opens a document over a persistent connection, usually a WebSocket or long-poll channel, to a stateless connection gateway. The gateway routes that session to the collaboration service instance that currently owns the document. Ownership matters: for each active document, exactly one authoritative process serializes incoming operations into a single ordered stream, assigning each operation a monotonically increasing revision number. Before an operation is committed, the Operational Transformation engine transforms it against any operations the sender had not yet seen, so the result is consistent no matter what order clients submitted in. The committed, transformed operation is appended to a durable operations log and broadcast to every other connected client, who apply it to their local copy. A document store holds the base state and periodic snapshots, so opening a document means loading the latest snapshot and replaying the tail of the op log rather than replaying from the beginning. A presence service tracks who is connected, where their cursor sits, and what they have selected, fanning that out on a lighter, lossy channel since presence does not need durability. A separate persistence pipeline compacts the log into snapshots and feeds version history. Permissions are checked at connection time and on every share change.
In a real interview, sketch this on the whiteboard before diving into any single box.
Core components
Walk through each service. The interviewer wants to hear what each one owns, not just the names.
Connection Gateway
Terminates WebSocket or long-poll connections, authenticates the session, and routes each client to the collaboration instance that owns its document. Stateless and horizontally scalable.
Collaboration Service (per-document owner)
The authoritative serializer for one document. Assigns revision numbers, runs OT transforms, commits operations to the log, and broadcasts them to connected clients. Exactly one owner per active document at a time.
OT / CRDT Engine
The concurrency core. Transforms an incoming operation against concurrent operations it did not observe, so every client converges. This is where insert and delete positions get adjusted for edits that happened in parallel.
Operations Log
An append-only, durable record of every committed operation with its revision number and author. Source of truth for convergence, offline catch-up, and version history.
Document Store and Snapshots
Holds materialized document state plus periodic snapshots so opening a document is fast and replay is bounded.
Presence Service
Tracks connected users, cursor positions, and selections. Uses a lossy, low-latency channel because a dropped cursor update self-heals on the next one.
Permission and Sharing Service
Resolves who can view, comment, or edit a document, enforced at connect time and re-checked when sharing changes.
Data model
Pick the right store per table. Justify each choice with the access pattern, not by reflex.
documentsdoc_idowner_idtitlecurrent_revisionlatest_snapshot_idcreated_atupdated_atOne row per document. current_revision is the highest committed operation number and is used to detect how far behind a reconnecting client is.
operationsdoc_idrevisionauthor_idop_typeop_payloadcommitted_atAppend-only log, primary key (doc_id, revision). op_payload encodes the insert, delete, or formatting change after transformation. This log drives convergence, offline sync, and history.
doc_snapshotssnapshot_iddoc_idrevisioncontent_blobcreated_atMaterialized document state at a given revision. Opening a doc loads the latest snapshot then replays operations with revision greater than snapshot.revision.
permissionsdoc_idprincipal_idprincipal_typerolegranted_atprincipal_type is user, group, or link. role is viewer, commenter, or editor. Checked on connect and on every share mutation.
presence_sessionsdoc_idsession_iduser_idcursor_positionselection_rangelast_seen_atEphemeral, often held in memory or a fast cache with a short TTL. Not part of the durable document, since presence is disposable.
commentscomment_iddoc_idauthor_idanchor_rangebodyresolvedcreated_atComments and suggestions anchor to a text range. Anchors must be repositioned as the underlying text shifts, similar to how cursors are transformed.
Deep dives
These are the conversations the interviewer is steering you toward. Practice each one until you can talk through it without notes.
Operational Transformation and convergence
Every edit is expressed as a small operation, for example insert the character x at position 12 or delete one character at position 5. The problem is that two users generate operations against the same base version at the same time. If user A inserts at position 3 and user B deletes at position 1, applying B's operation shifts everything, so A's position 3 is now wrong. Operational Transformation fixes this by transforming each incoming operation against the operations it did not see before applying it. The transform adjusts positions so the intent is preserved and, crucially, so that transforming A against B and B against A yields the same final document on both clients. Getting the transform functions correct for every pair of operation types (insert vs insert, insert vs delete, delete vs delete, plus formatting) is the genuinely hard part, and subtle bugs cause documents to diverge.
CRDTs as the alternative
Conflict-free Replicated Data Types take a different approach. Instead of transforming positions, each character gets a stable, globally unique identifier, often a fractional or dense index that sorts between its neighbors, so insert and delete are commutative by construction. Two replicas that receive the same set of operations in any order converge without a central transform step. The appeal is that CRDTs can work peer to peer and tolerate out-of-order delivery well. The cost is metadata: every character carries identity data, and tombstones for deleted characters accumulate, so memory and garbage collection become real concerns for large, long-lived documents. Text CRDTs like RGA, Logoot, and Yjs address this, but the tradeoff of simpler merging against heavier per-character overhead is the crux of OT vs CRDT.
Single authoritative server per document
The reason a per-document owner exists is total ordering. If one process assigns every operation a sequential revision number, then the whole convergence problem collapses to transforming each new operation against the small set of operations committed after the client's last known revision. This is far simpler and cheaper than a fully symmetric peer-to-peer merge. The tradeoff is that document ownership must be tracked and failed over. If the owner instance dies, another instance must take ownership, load the latest snapshot plus tail of the log, and resume, without ever committing two different operations at the same revision. Fencing tokens or a lease from a coordination service prevent split-brain double ownership.
Presence and remote cursors
Showing where other people are typing is a separate, softer problem. Cursor and selection updates are frequent and disposable: if one update is lost, the next one corrects it within a fraction of a second, so this data flows on a lossy, low-durability channel rather than the committed operation log. The subtle part is that a remote cursor position must be transformed exactly like an operation. If a collaborator's cursor sits at position 20 and someone inserts five characters before it, that cursor must move to 25 on every screen, otherwise cursors drift away from the text they were attached to. Comment anchors and suggestion ranges need the same transformation treatment.
Offline editing and reconciliation
When a client goes offline it keeps editing a local copy, queuing operations against the last revision it saw. On reconnect, the server has likely advanced many revisions. The client sends its queued operations tagged with its stale base revision, and the server transforms them forward against everything committed in the meantime before assigning them fresh revision numbers. The client in turn receives the operations it missed and transforms its local pending queue against them. Done correctly, both sides converge and no keystroke is lost. The risk cases are long offline windows and edits to text that other people deleted while you were gone, which the transform rules must resolve deterministically rather than dropping work silently.
Version history and snapshotting
Because every operation is stored, the full edit history is already captured. Version history is a view over the operations log: to reconstruct the document at any past revision, start from the nearest earlier snapshot and replay operations up to that revision. Replaying from revision zero would be far too slow for a large document, so the persistence pipeline periodically compacts the log into a snapshot, say every few hundred operations or every few minutes of activity. Named versions and the timeline UI are then cheap to build. Older fine-grained operations can be down-sampled or archived to cold storage while keeping named checkpoints, which bounds storage growth for documents edited over years.
Large-document performance and selection stability
As documents grow to hundreds of pages, replaying operations and re-rendering on every keystroke gets expensive. Practical systems keep an in-memory materialized model on both client and server, apply operations incrementally rather than recomputing from scratch, and snapshot aggressively so open time stays low. Selection stability is a usability concern that falls out of the same transform machinery: a user's own selection and the visible cursors of others must all be repositioned consistently as concurrent edits land, so that no one's cursor jumps to the wrong place. Batching several keystrokes into one network flush also cuts operation volume without hurting perceived latency.
Trade-offs to discuss
Every senior interviewer expects you to surface at least 3 of these. Pick the decisions, state the alternatives, and justify your choice.
Operational Transformation vs CRDTs
OT keeps operations small and works cleanly with a central authoritative server, but the transform functions are intricate and error-prone. CRDTs merge commutatively and suit peer-to-peer and offline-heavy cases, but carry per-character metadata and tombstone overhead. Google Docs chose OT; several newer editors chose CRDTs.
Single authoritative server per document vs peer-to-peer
A per-document owner gives a clean total order that makes OT tractable and cheap, at the cost of ownership tracking and failover. Peer-to-peer avoids a single point of coordination but pushes far more complexity into the merge, which is why it usually pairs with CRDTs.
Store every operation vs snapshots only
Keeping every operation gives perfect history and precise offline reconciliation but grows unbounded. Snapshots alone are compact but lose fine-grained history. The practical answer is both: full op log plus periodic snapshots, with old ops archived.
Durable committed edits vs lossy presence
Committed text operations must be durable and never lost. Cursor and presence updates are high frequency and self-correcting, so making them durable would waste resources. Splitting these onto different channels is a deliberate consistency-vs-cost tradeoff.
Strong convergence vs eventual per-client view
The final converged document must be identical for everyone, which is non-negotiable. Intermediate views can briefly differ between clients while operations are in flight, and that momentary divergence is accepted in exchange for low input latency.
Snapshot frequency
Frequent snapshots make document open fast and bound replay cost but consume more storage and write bandwidth. Infrequent snapshots save storage but slow document load and history reconstruction. The cadence is tuned per document activity.
Locking regions vs full concurrent editing
Locking a paragraph while someone edits it would remove conflicts entirely but destroys the real-time feel. Full concurrent editing keeps the experience fluid and pushes all the hard work into the transform engine, which is the whole point of the product.
How Google Docs actually does it
Google Docs uses Operational Transformation, and its lineage traces back to research on OT and to Google Wave, whose collaborative editing model was later described publicly. When Google rebuilt Docs in 2010 the team wrote about moving to a character-by-character OT model that made real-time co-editing feel instant. For contrast, several modern collaborative tools chose CRDTs instead: Figma's engineering team has written in detail about their multiplayer approach, and libraries like Yjs and Automerge popularized CRDT-based editing. The practical takeaway for an interview is that both OT and CRDTs are correct, production-proven answers, and the interesting discussion is the tradeoff between them rather than declaring one universally better.
Lessons to study before this interview
If any of these topics are fuzzy, the interviewer will catch it. Each lesson is 15 to 60 minutes with diagrams, code, and a quiz.