Real-Time Systems

CRDT vs. OT: Real-Time Data Sync Algorithms Explained

Dive deep into CRDTs and OTs, two powerful algorithms for real-time data synchronization. Understand their architectures, trade-offs, and use cases for collaborative apps.

Khader Vali August 9, 2026 6 min read

CRDT vs. OT: Real-Time Data Sync Algorithms Explained

In today’s hyper-connected world, real-time collaboration isn’t just a feature; it’s an expectation. From shared document editors like Google Docs to collaborative whiteboards, gaming, and even distributed databases, the ability for multiple users or systems to interact with and update the same data simultaneously, and see those changes reflected instantly, is paramount. But achieving this seemingly simple feat in a robust, scalable, and consistent manner is one of the most challenging problems in distributed systems.

The core of this challenge lies in data synchronization and conflict resolution. When multiple users concurrently modify the same piece of data, how do you ensure that everyone sees a consistent, correct, and eventually identical state, without losing any changes? This is where algorithms like Operational Transformation (OT) and Conflict-Free Replicated Data Types (CRDTs) step in.

As a senior software engineer, I’ve wrestled with these problems and built systems that rely on these paradigms. In this comprehensive guide, we’re going to deep-dive into both OT and CRDTs. We’ll explore their underlying principles, architectural considerations, practical implementations with code examples, and the trade-offs involved in choosing one over the other. By the end, you’ll have a solid understanding of how these powerful tools enable the real-time experiences we’ve come to expect.

The Core Problem: Concurrency and Consistency

Imagine two users, Alice and Bob, editing the same text document. Alice types “Hello world” and Bob, at almost the exact same time, types “Goodbye world” right after Alice’s text. If both changes are simply applied sequentially, the outcome depends on which change arrives first. If Alice’s arrives first, then Bob’s, the document might end up as “Hello worldGoodbye world”. But what if Bob inserted his text *before* Alice’s, but his network was slower? Without a proper synchronization mechanism, the final state could be incorrect, or worse, changes could be lost.

This is the classic “lost update” problem, a fundamental challenge in concurrent systems. In a distributed environment, this problem is exacerbated by network latency, partitions, and the inherent uncertainty of message ordering. The CAP theorem reminds us that in the presence of network partitions, we must choose between Availability and Consistency. For real-time collaborative applications, we often strive for a balance, leaning towards eventual consistency while providing a good user experience.

The goal of real-time data synchronization algorithms is to provide a mechanism by which a shared data structure (like a text document, a counter, a set of items) can be concurrently modified by multiple users, potentially across different machines and networks, and eventually converge to the same correct state on all replicas, regardless of the order in which operations are applied or network failures.

CRDT vs. OT: Real-Time Data Sync Algorithms Explained
Generated Image

Operational Transformation (OT)

Operational Transformation is arguably the most well-known algorithm for real-time collaborative editing, largely thanks to its pioneering use in Google Docs. It’s a server-centric approach designed to maintain consistency across multiple replicas of a shared document.

What is Operational Transformation?

At its heart, OT is about transforming operations. When a client performs an action (e.g., inserting a character, deleting a word), it generates an “operation” describing that change. This operation is then sent to a central server. The magic of OT happens when the server receives an operation from one client, but its own document state (or the state it’s about to apply the operation to) has already been updated by a concurrent operation from another client. In such cases, the server transforms the incoming operation so that it can be applied correctly to the *current* state of the document, preserving the *intent* of the original operation.

The core principle is called “intent preservation.” If Alice inserts ‘A’ at position 0, and Bob concurrently inserts ‘B’ at position 0, both intend to add their character at the beginning. If Alice’s operation arrives first, the document becomes “A”. When Bob’s operation arrives, it needs to be transformed. If it’s applied naively, it would become “BA”. But Bob intended to insert at position 0 *of his original document*. To preserve intent, Bob’s operation (insert ‘B’ at pos 0) should be transformed against Alice’s (insert ‘A’ at pos 0) to become an “insert ‘B’ at pos 1”. The result would then be “AB”.

How Operational Transformation Works: Architecture in Words

An OT system typically operates in a client-server model:

  1. Central Server: The server holds the canonical version of the document and is responsible for sequencing and transforming operations. It acts as the single source of truth.
  2. Clients: Each client maintains its own local copy of the document. When a user makes a change, the client generates an operation and sends it to the server.
  3. Operation Sequencing: The server receives operations from various clients. It assigns a unique sequence number to each operation, establishing a total order.
  4. Transformation: This is the most complex part. When the server receives an operation (let’s call it OpA) from a client, it checks if its own document state has diverged from the state that OpA was based on. If there are other operations (OpB, OpC, etc.) that have been applied to the server’s document since OpA was generated, then OpA must be transformed against each of these concurrent operations. The transformation function, T(OpA, OpB), takes OpA and OpB and returns a new operation OpA' that, when applied to a state that already incorporates OpB, produces the same result as if OpA was applied first, then OpB.
  5. Application and Broadcast: After transformation (if needed), the server applies the modified operation to its canonical document. It then broadcasts this transformed operation (or the original if no transformation was needed) to all other connected clients, informing them of the new canonical state.
  6. Client Update: Clients receive operations from the server. They apply these operations to their local copy, often adjusting their own pending operations if they have any, to maintain consistency. This often involves a client-side transformation matrix as well, to transform local pending operations against incoming server operations.

A key concept here is the “history” or “versioning” of the document. Both the server and clients track the version of the document that an operation is based on. This allows the server to identify which operations need to be transformed against which other operations.

Code Example: Conceptual OT for Text

Implementing a full OT system is notoriously complex due to the exponential number of transformation cases. However, we can illustrate the basic idea with a simplified example for text editing operations.

Consider two basic operations: insert and delete. Each operation has a type, a position, and a value/length.

class TextOperation {
constructor(type, position, valueOrLength) {
this.type = type; // 'insert' or 'delete'
this.position = position; // The index in the string
this.value = (type

Written by

Khader Vali

Senior Software Engineer specializing in cloud architecture, real-time systems, and enterprise-scale applications.

Share this article

Related Articles

WebTransport & WebRTC: Next-Gen Real-Time Communication

Sep 30, 2026 · 6 min read

CRDT vs. OT: Real-Time Data Sync Algorithms Explained

Sep 09, 2026 · 8 min read

WebSocket Scaling Patterns for 100K+ Concurrent Connections

May 12, 2026 · 2 min read