On this page
Before you start
This lesson uses ideas from these earlier lessons. Read them first if any idea is new to you.
01Why interviewers ask this
The interviewer says: "Design a shared document, like Google Docs. Two people type in the same sentence at the same moment. Both must see the same text, and nobody's typing may vanish."
A weak answer saves the whole file on each key press, or locks the document for one editor. A strong answer sends small edits, not files. It says how edits made at the same time are put in one order or merged, and what that costs. It also covers cursors, undo and saved history.
This is an SDE-3 question. At SDE-2 level you should know why whole-file saves lose edits. At SDE-3 level you should work an example of both methods and compare them.
02The idea in plain words
Two people read the same shop list. Ravi says "put milk as the 1st item". At the same time Asha says "cross out the 3rd item". If Ravi's change lands first, Asha's "3rd" now points to a different item. Numbers shift when others edit.
Sending the whole file does not work either: the last save wins and the other edits vanish (last write wins, lesson 78). So we send operations. An operation is one small edit: "insert x at position 5" or "delete the character at position 2". There are two ways to keep operations correct.
Operational transformation (OT)
OT fixes the shifted numbers. One server puts all operations in a single order and keeps them in a log with revision numbers.
- The client applies its own edit at once, so typing feels instant. It sends the operation with the revision it last saw.
- The server may be on a newer revision. It transforms the operation against each operation that was applied since: it changes the position so that the operation means the same thing now.
- The server adds it to the log and sends it to every client. A client transforms the incoming operation against any edit of its own that is still waiting.
The rules for inserts and for deletes of one character are short. "Earlier" means earlier in the server order.
- An insert moves right by the length of an earlier insert that is at the same position or before it. At the same position the earlier one goes first, or the copies would differ.
- An insert moves left by one if an earlier delete was before it.
- A delete moves right by the length of an earlier insert at or before it. It moves left by one if an earlier delete was before it.
- If two deletes hit the same character, the second one does nothing.
Google described this client and server design for Google Docs in 2010.
CRDT for text
From lesson 78, a conflict-free replicated data type (CRDT) is a data type that you can copy to many places. The authors of the idea define it so. Any copy can change without asking another copy. Any two copies that have received the same updates reach the same state.
For text, give every character a unique ID, such as a client number and a counter (like the clocks of lesson 77). An insert says "put this character after the character with ID x". IDs never change, so nothing shifts. A delete does not remove the character. It marks it as deleted, a tombstone, because another copy may still say "insert after x". If two people insert after the same character, a fixed rule on the IDs decides the order. For example, the larger ID goes first. So every copy agrees. Updates can arrive in any order, and no server is needed.
Comparing the two
| OT | CRDT | |
|---|---|---|
| Central server needed | Yes, for the order | No |
| Offline editing | Harder: long waiting edits must be transformed | Natural |
| Memory and history | Small: plain text and a log | Bigger: an ID per character, tombstones |
| What is hard | Correct transform rules for every pair of operations | The structure, its size, and cleaning old tombstones |
Around the algorithm
- One server for each document. All editors of a document connect to the same server, by WebSocket (lesson 107). A lookup table or a hash of the document ID chooses the server. That server orders or relays operations.
- Cursors and presence (who is online). A cursor is not part of the document. Send it as a small message, and do not store it. In OT, shift a cursor like any position. In a CRDT, anchor it to a character ID, so it does not shift. A user with no heartbeat for a while is shown as offline.
- Undo. Undo must reverse your own last edit, not the last edit of anyone. Keep a stack of your own operations and apply the reverse of one, transformed against what came after.
- Reconnecting. A client that lost its connection sends the last revision it saw. The server replies with the operations it missed.
- History. Store every operation in a log. Save a snapshot of the whole text now and then. To open a document, load the newest snapshot and replay the operations after it.
A third option: settle each property
A design tool, such as a canvas, has many objects with a few properties each: x, y, colour. The server stays the single authority and keeps the latest value of each property. Two people who change different properties both win. Two who change the same property: the later one wins (last write wins for that property). This is simpler than OT and CRDTs. It is a poor fit for the characters inside one text. A whole paragraph would be one property, and one person's typing would be lost.
Want to check your understanding? Try explaining this idea in your own words. You can continue reading first, or ask the AI tutor a question. Sign up free to ask the tutor
03Pause and predict
Pause. Guess first.
Ravi inserts 3 characters at the start of a document. Asha, working on the old text, inserted "!" at position 5. If Ravi's change is applied first, at which position must her insert go?
Write your guess before you read on. The answer is in the worked example.
04Worked example
The document says HELLO at revision 0. Three people edit at the same time, all on revision 0. Positions start at 0.
- Ravi: insert ">> " (3 characters) at position 0.
- Sunita: delete the character at position 1, which is E.
- Asha: insert "!" at position 5, the end.
Step 1: whole-file saves. Each saves the file she sees. The last save wins, so 2 of the 3 edits are lost.
Step 2: OT. The server receives them in this order: Ravi, Sunita, Asha.
- Ravi: no earlier edit. Insert at 0. Text: ">> HELLO", revision 1.
- Sunita: Ravi's insert at 0 is before her position 1, so move right by 3: delete at 4. Text: ">> HLLO", revision 2.
- Asha: against Ravi's insert, 5 moves to 5 + 3 = 8. Against Sunita's delete at 4, which is before 8, move left by 1: 7. Insert at 7. Text: ">> HLLO!".
Against Ravi alone the answer to the predict box is 8; Sunita's delete then moves it to 7. Without the transform, an insert at 5 would give ">> HL!LO", which is wrong. Every client reaches ">> HLLO!".
Step 3: a tie. Asha inserts "!" and Bina inserts "?", both at position 5. The server takes Asha first. Bina's position moves to 6. The result is "HELLO!?" in every copy.
Step 4: CRDT, the same edits. The letters have IDs c1 to c5. Asha's "!" is "after c5". Ravi's three characters are each "after" the one before, starting from the document start. Sunita marks c2 as deleted. The three updates can arrive in any order. Every order gives ">> HLLO!", and nothing is transformed.
Step 5: memory. Assumption: a document of 100,000 characters of 1 byte each, and 25 bytes of ID and links for each character. OT keeps 100,000 bytes of text. A CRDT keeps 100,000 x 25 = 2,500,000 bytes = 2.5 MB, which is 25 times more. If the editors also typed and deleted 200,000 more characters, the tombstones add 200,000 x 25 = 5 MB. Total 7.5 MB, 75 times the text. Real libraries pack runs of characters typed in order into one item, so they use less.
Step 6: offline. A phone types for 10 minutes at 5 operations per second: 3,000 operations. Others made 600 in that time. OT must transform each of the 3,000 against the 600: 3,000 x 600 = 1,800,000 transforms. Assumption: 1 microsecond each, so 1.8 seconds.
Step 7: history. A document has 500,000 operations of 50 bytes each: 25 MB. A replay of all operations at 100,000 per second takes 5 seconds. With a snapshot every 1,000 operations, opening replays at most 999: 0.01 seconds.
Step 8: servers. Assumption: 3,000,000 editors online at peak, and one server holds 50,000 connections (lesson 107). Servers: 3,000,000 / 50,000 = 60.
What companies wrote
- Google wrote on 23 Sep 2010 that Google Docs clients and a server use operational transformation. A client transforms a remote change against its own waiting change, and the server keeps a revision log. That post is from 2010, so today's design is not confirmed. Link: https://drive.googleblog.com/2010/09/whats-different-about-new-google-docs.html (opens in a new tab)
- Figma wrote on 16 Oct 2019 that it chose not to use OT, which it called very complicated and hard to implement correctly. Its system is inspired by CRDTs but is not a true one. The server is the central authority, and the latest value of each property wins. Link: https://www.figma.com/blog/how-figmas-multiplayer-technology-works/ (opens in a new tab)
05Trade-offs
OT solves shifted positions with a small server state and a small log. It costs a central server and hard transform rules, and a long offline stretch costs a pile of transforms (1,800,000 here). A CRDT solves offline editing and having no server, and it costs memory (25 to 75 times the text here). Property-by-property settling is the simplest, and it costs lost typing inside one text. I would use OT for text with a server, a CRDT where offline editing matters, and property rules for canvases.
06Common misconceptions
"A CRDT needs no server." The merge needs none. But users still need a place that stores the document and checks who may edit.
"OT just adds a number to each position." The shift depends on the type and place of every earlier operation, and ties need a rule. In step 2 the position moved right, then left.
"Deleted characters can be removed at once." Another copy may still insert after one. A tombstone can go only when every copy has seen the delete. The Yjs library, for example, throws away the content of a deleted item but keeps a small marker.
07How to say it in the interview
Say it like this
I would send operations, not files, and use operational transformation on one server for each document. If offline editing matters, I would use a CRDT, which costs more memory.
08Check your understanding
- In OT, what does the server do to an operation made on an older revision? In a CRDT, why is a deleted character kept?
- The text is ABCDE at revision 0. Ben inserts "XY" at position 1. Chen deletes position 3. Dev inserts "!" at position 5. All three work on revision 0. The server order is Ben, Chen, Dev. Give the final position of Chen's and Dev's edits, and the final text.
- A team builds a design tool where users drag shapes (x, y, colour). They plan to use a text CRDT for everything. What do you say?
09Answers
Show the answers
- It transforms the operation against every operation applied since that revision, so that the position means the same thing now. A deleted character is kept because another copy may still insert after it.
- Ben: insert at 1, text AXYBCDE. Chen: 3 is after 1, so 3 + 2 = 5, delete at 5 (D). Text AXYBCE. Dev: 5 + 2 = 7 against Ben, then against Chen's delete at 5, which is before 7: 6. Insert at 6. The final text is AXYBCE!.
- Each shape has a few independent properties, so keep the server as the single authority and keep the latest value of each property. A text CRDT costs memory for a problem that does not exist. Use OT or a CRDT only inside a text label.
10Summary card: collaborative editing
One-page summary
- Send operations, not files. Numbers shift when others edit, and the last save wins.
- OT: one server orders operations in a revision log and transforms each late one against the operations it missed. Example: position 5 became 8, then 7. Ties need a rule.
- CRDT for text: a unique ID for each character, insert "after x", delete marks a tombstone. Any order gives the same text, and no server is needed. The cost is memory (25 to 75 times the text in the example).
- Around it: one server for each document, cursors as small messages, undo of your own edits, an operation log with snapshots.
- A third option: the server keeps the latest value of each property. Fine for canvases, wrong for text.
- Trap: choosing a text algorithm for a problem of independent properties.
11Sources
- Google Drive Blog, 23 Sep 2010, "What's different about the new Google Docs: Making collaboration fast": https://drive.googleblog.com/2010/09/whats-different-about-new-google-docs.html (opens in a new tab) (checked 26 Oct 2026). It describes Google Docs in 2010, not today.
- Figma, 16 Oct 2019, "How Figma's multiplayer technology works": https://www.figma.com/blog/how-figmas-multiplayer-technology-works/ (opens in a new tab) (checked 26 Oct 2026).
- CRDT definition: Preguica, Baquero and Shapiro, "Conflict-free Replicated Data Types", 2018: https://arxiv.org/pdf/1805.06358.pdf (opens in a new tab) (checked 26 Oct 2026). The original paper (Shapiro and others, 2011) could not be opened: its address returned an access-check page. The definition here comes from the 2018 entry by the same authors. Text CRDT with unique IDs and tombstones: Kleppmann and Beresford, "A Conflict-Free Replicated JSON Datatype": https://arxiv.org/pdf/1608.03960 (opens in a new tab) (checked 26 Oct 2026). Yjs internals (an ID per character, a deleted flag): https://github.com/yjs/yjs/blob/main/INTERNALS.md (opens in a new tab) (checked 26 Oct 2026). Yjs says updates can be applied in any order: https://docs.yjs.dev/ (opens in a new tab) (checked 26 Oct 2026).
- All sizes, rates, times and counts in the worked example are assumptions made for teaching. The transform rules are the simple rules for inserts and deletes, and the steps were checked with a short program.
Try what you just learned
Put this idea into practice with a short exercise or a relevant tool. Free to try. No sign-up needed.
More practice. This needs a free account.
What to learn next
Continue learning with the lessons that build on this one.
- Batch processing and data warehouses: files, columns and star schemas
- Multi-tenancy: shared tables, schema per tenant or database per tenant
- Stream processing: windows, late data, exactly-once
Practise this idea
Have a question about this lesson?
Ask the AI tutor to explain a difficult idea, walk through an example or check your understanding. It uses the lesson to help you work through the topic.
A free account includes 10 AI tutor questions a day. The lesson remains free to read without an account.
All lessons in Module 23: Big systems in depth
Prefer another topic? Browse all 169 lessons.