OT for Text
Operations are insert(pos, text) and delete(pos, len). These two primitives cover every edit — a replacement is a delete followed by an insert — which is why the operation set stays this small. This is the foundation of any real-time collaborative editing system; interviewers often ask why the client sends operations instead of the whole document, and the answer is that character-level ops let concurrent edits merge instead of overwriting each other.
Transformation Function
transform(op1, op2) adjusts positions of concurrent ops to maintain convergence. Example: if op1 inserts before op2 position, op2 position shifts by op1.length. Interviewers probe the transform properties: TP1, where both sides converge to the same document after each applies the other’s transformed op, and TP2, the harder guarantee needed when the same pair of ops can be transformed in different orders. The edge cases that trip candidates up are two inserts at the identical position (you need a tie-breaker, usually the client id) and a delete whose range overlaps a concurrent insert.
Server Algorithm
Server serializes all ops; each client sends op with client_revision; server transforms against all ops since that revision. This central-server model is the version most teams ship, because it avoids the hardest peer-to-peer transform cases: the server is the single source of truth for ordering. In a system design interview, the detail to get right is that the server transforms the incoming op against the exact suffix of the op log after client_revision, applies it, then assigns the next revision number and returns it as an acknowledgement.
Data Schema
Document Table
Document (
id UUID,
content TEXT,
revision INT
)
Operation Table
Operation (
id UUID,
doc_id UUID,
revision INT,
type ENUM(insert, delete),
position INT,
text TEXT, -- for insert
length INT, -- for delete
client_id TEXT,
created_at TIMESTAMP
)
Operation Flow
Client sends op
→ Server receives
→ Transform against ops since client_revision
→ Apply to document
→ Broadcast transformed op to other clients
Client receives server op
→ Transform against pending local ops
→ Apply
Diamond Problem
op1 and op2 concurrent: server applies op1, transforms op2 against op1, sends transformed op2 to client who sent op1; client transforms op2 against their pending ops. The subtle part interviewers watch for is the client’s own in-flight ops: an op that has been sent but not yet acknowledged must still be transformed against the incoming server op, or the two replicas drift apart. Tracking that pending queue correctly is what separates a working implementation from one that silently corrupts the document.
Cursor Position Preservation
Cursor ops transformed alongside text ops to maintain correct cursor positions for all participants. A concrete case interviewers like: when a remote insert lands before your cursor, your cursor must shift right by the inserted length, but an insert at the exact cursor position needs a rule for whether the cursor stays put or moves — otherwise two users typing at the same spot see their carets jump unexpectedly.
See also: Atlassian Interview Guide
See also: Meta Interview Guide 2026: Facebook, Instagram, WhatsApp Engineering
Keep sharpening your system design:
