collaborationinfrastructure

Real-Time Collaboration with Durable Objects

How we use Cloudflare Durable Objects and WebSockets for zero-conflict real-time editing.

February 28, 2026


LixSketch uses Cloudflare Durable Objects for real-time collaboration. Each canvas room is a single Durable Object instance that coordinates all connected users via WebSockets.

Why Durable Objects?

Traditional WebSocket servers have a problem: if you have multiple server instances, you need a pub/sub layer (Redis, NATS, etc.) to broadcast messages between them. Durable Objects solve this by guaranteeing that all connections to a room are handled by a single instance.

This means:

  • No external pub/sub needed
  • No message ordering issues
  • State is always consistent
  • Automatic scaling per room

The Architecture

When a user joins /room/{roomId}:

  1. 1.WebSocket upgrade — the browser opens a WebSocket to the Cloudflare Worker
  2. 2.Routing — the Worker routes the connection to the Durable Object for that roomId
  3. 3.State sync — the DO sends the current canvas state to the new user
  4. 4.Broadcasting — any change from one user is broadcast to all others in the room
Rendering diagram...

Message Protocol

Each WebSocket message is a JSON object with a type field:

  • join — user enters the room (includes guest profile)
  • leave — user disconnects
  • sync — full state snapshot (sent to new joiners)
  • delta — incremental change (shape added/moved/deleted)
  • cursor — cursor position update (throttled to 60fps)
  • presence — list of active users in the room

Deltas are the key to performance. Instead of sending the full canvas state on every change, we send only what changed:

json
{
  "type": "delta",
  "action": "move",
  "shapeId": "rect-abc123",
  "data": { "x": 150, "y": 200 }
}

Conflict Resolution

Since all messages go through a single Durable Object, ordering is guaranteed. The DO processes messages sequentially, so there are no conflicts. If two users move the same shape simultaneously, the last write wins — which is the expected behavior for a visual canvas.

Presence & Cursors

Each user's cursor position is broadcast to the room at up to 60fps. The Durable Object doesn't persist cursor data — it's ephemeral, only forwarded to other connected users.

User presence (who's in the room) is tracked by the DO and broadcast whenever someone joins or leaves.