CRDT/OT Synchronization for Real-Time Applications

Two developers editing the same JSON configuration file simultaneously. Within a minute—desync, lost edits. This scenario is familiar to anyone working with concurrent access. Simple event broadcasting via WebSocket breaks under simultaneous changes. Without a formal data model, conflicts are inevit

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1281
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1237
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    977
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1026
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1103
  • image_website-_0.webp
    Website development for Red Pear
    550

Two developers editing the same JSON configuration file simultaneously. Within a minute—desync, lost edits. This scenario is familiar to anyone working with concurrent access. Simple event broadcasting via WebSocket breaks under simultaneous changes. Without a formal data model, conflicts are inevitable. Our team, with 10 years of experience, implements CRDT and OT for conflict-free synchronization. The solution reduces development time by 30% and pays for itself in 3–4 months, saving up to 40% of the development budget.

Problems That CRDT Solves

Concurrent access — when two users modify the same object, without a special model edits are lost or overwritten. CRDT guarantees that all copies converge to one state. Offline mode — a user makes changes without internet, and upon reconnection they automatically sync. OT requires a constant connection. Implementation complexity — writing your own OT for more than two clients involves dozens of edge cases. CRDT with ready-made libraries (Yjs, Automerge) gives a working solution in days.

How CRDT and OT Work: Fundamental Difference

OT (Operational Transformation) transforms operations considering concurrent changes. The method behind Google Docs, it only works with a central server-arbiter. For >2 clients, implementation becomes exponentially complex. CRDT (Conflict-free Replicated Data Types) are data structures that mathematically guarantee consistency without coordination. Operations are commutative and idempotent. More on Wikipedia.

Criterion OT CRDT
Central Server Mandatory Optional (P2P)
Offline Support Difficult Native
Performance High Depends
Implementation Complex, many edge cases Simpler with ready libraries
Rich Text Google Docs, Quill Yjs, Automerge

Why CRDT Is Relevant for Modern Applications?

CRDT wins in offline, P2P, and single-point-of-failure scenarios. Yjs reduces development time by 2–3 times compared to custom OT—ready integrations without transformation logic. OT remains for high-load text editors, but for most web applications CRDT is more practical. Integration cost is reduced by 30% by eliminating custom solutions. For a client building a collaborative whiteboard, we integrated Yjs with WebSocket persistence. The result: zero sync conflicts, offline editing support, and a 40% reduction in development time compared to building custom OT.

How to Implement CRDT in 3–5 Days?

  1. Choose a library: Yjs for text, Automerge for complex JSON.
  2. Replace local states with shared types (Y.Doc, Y.Text, Y.Map).
  3. Deploy a WebSocket server (y-websocket or Hocuspocus) with persistence.
  4. Test concurrent access.
  5. Add awareness for cursors.

Below is a working configuration.

Example Integration with Yjs and WebSocket

npm install yjs y-websocket y-protocols 

Server (y-websocket):

// server.js const { WebSocketServer } = require('ws'); const { setupWSConnection } = require('y-websocket/bin/utils'); const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200); res.end('ok'); }); const wss = new WebSocketServer({ server }); wss.on('connection', (ws, req) => { setupWSConnection(ws, req, { docName: req.url.slice(1), gc: true, }); }); server.listen(1234); 

Client with Quill:

import * as Y from 'yjs'; import { WebsocketProvider } from 'y-websocket'; import { QuillBinding } from 'y-quill'; import Quill from 'quill'; const ydoc = new Y.Doc(); const provider = new WebsocketProvider( 'ws://localhost:1234', 'my-document-room', ydoc, { connect: true } ); provider.on('status', ({ status }) => { console.log('WS status:', status); }); provider.on('sync', (isSynced: boolean) => { if (isSynced) { console.log('Document synced from server'); } }); const ytext = ydoc.getText('quill-content'); const quill = new Quill('#editor', { theme: 'snow' }); const binding = new QuillBinding(ytext, quill, provider.awareness); provider.awareness.setLocalStateField('user', { name: 'Ivan Petrov', color: '#4a9eff', }); 

Data Storage: Persistence

Ephemeral y-websocket loses the document on restart. For production, we use Hocuspocus with PostgreSQL.

Example configuration

import { Server } from '@hocuspocus/server'; import { Database } from '@hocuspocus/extension-database'; import { Pool } from 'pg'; const pool = new Pool({ connectionString: process.env.DATABASE_URL }); const server = Server.configure({ port: 1234, extensions: [ new Database({ fetch: async ({ documentName }) => { const { rows } = await pool.query( 'SELECT data FROM documents WHERE name = $1', [documentName] ); return rows[0]?.data ?? null; }, store: async ({ documentName, state }) => { await pool.query( `INSERT INTO documents (name, data, updated_at) VALUES ($1, $2, NOW()) ON CONFLICT (name) DO UPDATE SET data = $2, updated_at = NOW()`, [documentName, Buffer.from(state)] ); }, }), ], }); server.listen(); 

Comparison of Yjs and Automerge

Criterion Yjs Automerge 2.x
Performance High for text Better for large JSON
Size ~30 KB gzip ~50 KB gzip (WASM)
Rich Text Quill, ProseMirror Direct JSON manipulation
P2P Via y-websocket Built-in networking
Documentation Extensive Good

Conflict Resolution: How CRDT Chooses a Winner

CRDT does not eliminate conflicts—it determines a deterministic winner. Yjs uses the YATA algorithm: insertion position is determined by neighboring elements, not an index, making it resilient to concurrent insertions. For Last-Write-Wins Map, the operation with the later timestamp wins. A border case: two users simultaneously delete and edit the same element—CRDT keeps a tombstone to correctly apply changes.

Scaling and Multi-Node Synchronization

A single WebSocket server does not scale horizontally. Solutions: Sticky sessions (nginx), Pub/Sub via Redis (Hocuspocus supports it natively), managed services (Liveblocks, PartyKit). Additional infrastructure savings: CRDT synchronization does not require an expensive central server. Our team configures a cluster with 99.9% uptime.

What We Deliver and Timelines

  • Architecture audit and data model analysis.
  • Library selection (Yjs, Automerge).
  • Backend integration (Node.js, PostgreSQL/Redis).
  • Development of custom shared types (boards, forms).
  • Persistence and multithreading setup.
  • Load testing at 5000 operations/sec.
  • Documentation and team training.

Timelines: basic integration 3–5 days, with persistence +2–3 days, multi-node +1 week. Contact us for a free consultation and project assessment. Order implementation—our engineers with 10+ years of experience have delivered dozens of successful projects.