Skip to main content
The sync protocol enables Convex’s reactive subscriptions by maintaining WebSocket connections with clients and efficiently notifying them of data changes. This is the foundation of Convex’s live-updating user interfaces.

Overview

Path: crates/sync/ The sync component provides:
  • WebSocket connection management
  • Query subscription tracking
  • Efficient change notification
  • State synchronization between client and server
  • Automatic reconnection handling

Architecture

Sync protocol flow

Connection establishment

  1. Client connects: Opens WebSocket to /sync
  2. Authentication: Client sends auth token
  3. Session creation: Server creates sync session
  4. Ready state: Connection is ready for subscriptions

Query subscription

  1. Client subscribes: Sends query with subscription ID
  2. Query execution: Server executes query in transaction
  3. Result returned: Initial results sent to client
  4. Read set tracked: Documents read are recorded
  5. Subscription registered: Changes will notify this subscription

Change notification

  1. Mutation commits: Database transaction commits
  2. Affected subscriptions: System identifies affected queries
  3. Notifications sent: WebSocket messages sent to clients
  4. Client re-queries: Client re-executes affected queries
  5. UI updates: React components re-render with new data

Protocol messages

Client to server

Server to client

Sync session implementation

Session struct

Handle subscription

Handle mutation

Change notification

Subscription matching

Subscription refresh

Optimizations

Batching updates

Multiple changes are batched:

Delta updates

Only send what changed:

Subscription deduplication

Multiple identical queries share subscription:

Client-side sync

The TypeScript client (npm-packages/convex/) implements the client side:

Connection management

React integration

React hooks use the sync protocol:

Performance characteristics

Latency

  • Initial query: Database query latency + network RTT
  • Updates: ~10-100ms from mutation commit to UI update
  • WebSocket overhead: ~1ms per message

Scalability

  • Connections per server: ~10,000 concurrent WebSockets
  • Subscriptions per connection: Hundreds to thousands
  • Update throughput: Thousands of notifications per second

Efficiency

Optimizations reduce bandwidth:
  • Incremental updates (only changed data)
  • Message batching (multiple updates combined)
  • Subscription deduplication (shared queries)
  • Compression (WebSocket compression enabled)

Testing

Sync protocol tests

Next steps