How the Macro Sync-Service Uses Cloudflare Workers for Real-Time Synchronization
The Macro sync-service runs as a Cloudflare Workers Durable Object that provides low-latency, real-time collaboration by combining WebSockets, CRDT-based document state, and edge-persistent storage.
The Macro open-source project implements its sync-service on Cloudflare's edge runtime to deliver scalable document collaboration. By leveraging Durable Objects, KV storage, D1 databases, and WebSockets, the service maintains mutable state in single-threaded isolates while persisting data across the global Cloudflare network.
Cloudflare Workers Durable Object Architecture
The sync-service's foundation is the DocumentSyncSession struct, declared with the #[durable_object] attribute in durable_object.rs. This annotation tells the Workers runtime to instantiate each document in its own isolated Durable Object.
#[durable_object] // ← Durable Object declaration
pub struct DocumentSyncSession { … } // services/sync-service/src/durable_object.rs
Each Durable Object provides:
- Single-threaded execution – Safe mutable state without locks
- Persistent identity – Survives across requests and restarts
- Location affinity – Runs at the edge closest to the first request
The module imports core Workers SDK types to interact with the runtime:
use worker::{
Cors, Date, DurableObject, Env, Error, Method, Request, Response,
WebSocket, WebSocketIncomingMessage, WebSocketPair, durable_object,
};
WebSocket-Based Real-Time Channel
When a client connects, the service upgrades HTTP requests to WebSocket connections using WebSocketPair::new(). This handshake occurs in websocket.rs, which handles the full lifecycle of real-time communication.
// sync-service/src/websocket.rs (excerpt)
pub async fn handle_connect(req: Request, env: Env, state: State) -> Result<Response> {
let pair = WebSocketPair::new()?;
let client_ws = pair[0].clone();
let server_ws = pair[1].clone();
let dss = state.get::<DocumentSyncSession>()?;
dss.register_ws(server_ws).await?;
Response::from_websocket(client_ws)
}
The Wsm wrapper manages socket metadata through maybe_update_ws_meta_map, tracking all connections in ws_meta_map. Incoming messages are parsed, applied to the CRDT document, and broadcast to every connected peer.
Client Connection Example
// TypeScript client (apps/web)
const docId = "12345";
const ws = new WebSocket(`wss://sync-service.${CLOUDFLARE_WORKER_SUBDOMAIN}/connect/${docId}`);
ws.onopen = () => console.log("Connected to sync service");
ws.onmessage = (e) => {
const update = JSON.parse(e.data);
// Apply update to local Loro CRDT instance
};
CRDT Document State with Loro
The service uses Loro, a Rust CRDT library, to represent document state through the DocumentState struct in state.rs. This approach eliminates merge conflicts by design.
// sync-service/src/state.rs (excerpt)
pub async fn save_snapshot(&self, snapshot: &[u8]) -> Result<()> {
let storage = self.session_storage.lock("save_snapshot")?;
storage.put(&self.document_id, snapshot).await?;
Ok(())
}
Each change is applied locally and immediately broadcast. New peers retrieve the latest snapshot via the dedicated snapshot endpoint, enabling instant catch-up without replaying full history.
Edge Persistence: KV and D1 Storage
The sync-service uses two Cloudflare storage systems with different consistency guarantees:
Durable KV for Document Snapshots
Writes to session_storage persist document state to Cloudflare KV, ensuring durability across Durable Object restarts. This is the hot path for real-time synchronization.
D1 SQLite for Metadata
d1.rs manages relational data including:
- Peer-to-user mappings
- Blame events for attribution
// sync-service/src/d1.rs handles batched writes to D1
This metadata is flushed periodically rather than on every operation, keeping the real-time path unblocked.
Keep-Alive and Scheduled Alarms
Cloudflare Workers support scheduled alarms that the sync-service uses to extend object lifetime. The keepalive.rs module implements this pattern:
- Prevents idle Durable Objects from garbage collection
- Flushes pending D1 writes on each alarm tick
- Maintains low latency for active sessions
// sync-service/src/keepalive.rs
// Alarm handler extends TTL and batches metadata persistence
This design ensures eventual consistency for relational data without sacrificing real-time performance.
Authentication and Access Control
Before any WebSocket upgrade or state modification, auth.rs validates JWT tokens and enforces access levels:
| Level | Permissions |
|---|---|
| read | Receive updates, cannot modify |
| write | Full collaborative access |
Unauthorized requests receive HTTP 401 via response(status_codes::UNAUTH).
Worker Entry Point and Request Routing
The cf_worker.rs file defines the top-level fetch handler that routes incoming HTTP requests to the appropriate Durable Object instance:
// sync-service/src/cf_worker.rs
// Worker entry point forwards routes to DocumentSyncSession
This separation allows the sync-service to scale horizontally—each document lives in its own Durable Object while sharing the same code and infrastructure.
Summary
- Durable Objects provide isolated, stateful contexts for each document in
durable_object.rs - WebSockets enable real-time bidirectional communication through
websocket.rs - Loro CRDT guarantees conflict-free concurrent editing in
state.rs - Cloudflare KV persists snapshots durably across restarts
- D1 database stores metadata with batched writes via
d1.rs - Scheduled alarms in
keepalive.rsextend object lifetime and flush pending data - JWT validation in
auth.rssecures all endpoints before access
Frequently Asked Questions
What makes Durable Objects suitable for real-time collaboration?
Durable Objects provide single-threaded execution with persistent identity, eliminating the need for distributed locking. Each document gets its own isolate that can hold mutable state and coordinate peers without cross-instance communication overhead.
How does the sync-service handle concurrent edits from multiple users?
The service uses Loro, a CRDT (Conflict-free Replicated Data Type) library. CRDTs guarantee that all peers converge to the same state regardless of edit ordering, eliminating the need for operational transformation or central locking.
What happens if a Durable Object restarts?
Document snapshots are persisted to Cloudflare KV via save_snapshot() in state.rs. When the Durable Object restarts, it retrieves the latest snapshot to restore state. Metadata in D1 is eventually consistent through the alarm-based flush mechanism.
Can the sync-service scale to millions of documents?
Yes—each document runs in its own Durable Object, so the architecture scales horizontally. Cloudflare automatically creates new Durable Object instances on demand and migrates them to optimal edge locations based on traffic patterns.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →