OT for Text
Operations are insert(pos, text) and delete(pos, len).
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.
Server Algorithm
Server serializes all ops; each client sends op with client_revision; server transforms against all ops since that revision.
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.
Cursor Position Preservation
Cursor ops transformed alongside text ops to maintain correct cursor positions for all participants.
{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “What operations does Operational Transform use for text editing?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “OT for text uses two operations: insert(pos, text) and delete(pos, len). The transformation function adjusts positions of concurrent ops so that applying them in any order yields the same final document state.”
}
},
{
“@type”: “Question”,
“name”: “How does the server handle concurrent OT operations?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “The server serializes all ops. Each client sends an op tagged with its client_revision. The server transforms the incoming op against every op applied since that revision, applies the result to the document, increments the revision, and broadcasts the transformed op.”
}
},
{
“@type”: “Question”,
“name”: “What is the diamond problem in OT?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “The diamond problem arises when op1 and op2 are generated concurrently. The server applies op1, transforms op2 against op1, and sends the transformed op2 to the client that sent op1. That client must then transform the received op2 against any pending local ops before applying it.”
}
},
{
“@type”: “Question”,
“name”: “How are cursor positions preserved during OT?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Cursor positions are treated as additional ops and transformed alongside text ops. When an insert shifts text after the cursor, the cursor position advances by the inserted length; when a delete removes text before the cursor, the cursor position decreases accordingly.”
}
}
]
}
See also: Atlassian Interview Guide
See also: Meta Interview Guide 2026: Facebook, Instagram, WhatsApp Engineering