Designing Trello's Real-Time Board Sync: Requirements, Minimal Architecture, and Operational Guardrails
Explore the minimal architecture behind Trello's real-time board sync, covering requirements, trust boundaries, operational metrics, failure modes, and when the design would need to evolve.
13 Jun 2026, 10:52 UTC

Requirements
Trello's real-time collaboration must deliver low-latency updates for board mutations (card moves, comments, checklist toggles) to every connected client while preserving a deterministic order of events. Clients may disconnect and reconnect frequently (tab closes, network hiccups, mobile backgrounding) and must be able to catch up without a full page reload. The system must also protect downstream services (search indexer, webhook dispatcher) from traffic spikes caused by a single misbehaving client.
Minimal Suitable Design
The smallest architecture that satisfies these requirements consists of three loosely coupled components:
- Stateless WebSocket gateway – accepts a persistent connection per browser tab, fans out board-scoped messages, and stores only connection metadata (subscriptions, last acknowledged sequence number) in a shared store.
- Shared Redis cluster – holds per-connection state keyed by a random connection ID; enables any gateway instance to resume a client's subscription after a load-balancer reroute.
- Client-side reconnection logic – on disconnect, the client opens a new WebSocket, sends its last acknowledged board sequence number, receives a snapshot of the current board state plus a delta log from that sequence, and resumes optimistic UI updates.
Messages flow as follows:
- Client applies an optimistic UI update locally and sends the mutation to the gateway.
- Gateway assigns a monotonically increasing board-level sequence number, persists the mutation to the board's event log, and fans the message to all subscribed connections.
- Each client receives the message, validates the sequence number (gap detection), and applies the update to its UI.
Example Connection URL
When the Trello UI loads, it opens a WebSocket similar to:
wss://trello.com/1/socket/<auth-token>
The <auth-token> is a short-lived, scoped credential that identifies the user and the board(s) the client is interested in. No sticky session is required; the gateway looks up the connection ID in Redis to retrieve stored subscriptions.
Trust and Data Boundaries
Trust boundaries are enforced at three points:
- Client → Gateway: The gateway validates the credential and checks that it grants access to the requested board ID before accepting the WebSocket upgrade.
- Gateway → Redis: All connection state is stored as opaque blobs; the gateway never trusts client-supplied sequence numbers beyond using them as a resume point.
- Gateway → Clients: Messages are scoped to a board ID; a client only receives mutations for boards it has explicitly subscribed to via the initial authentication handshake.
Cross-board operations (e.g., moving a card from Board A to Board B) are handled outside the WebSocket fan-out: the gateway coordinates a transaction via the backend service layer, then publishes two separate board-scoped events, each with its own sequence number. Do not assume webhook delivery for server-side integrations follows the same ordering as client updates; webhooks have independent retry and dead-letter semantics.
Operational Checks
To keep the system healthy, operators should monitor the following metrics and alerts:
- WebSocket connection count per gateway instance – sudden spikes may indicate a reconnection storm.
- Message latency percentiles (p50/p99) – measures the time from optimistic UI update to server acknowledgment; values consistently above 200 ms warrant investigation.
- Sequence gap alerts – if a client reports a missing sequence number, the gateway increments a counter; sustained gaps suggest message loss or Redis desynchronization.
- Rate-limit events (HTTP 429) – tracks per-connection throttling; a high rate may point to a misbehaving Power-Up or script.
- Redis health – memory usage, replication lag, and failed GET/SET operations; degradation triggers read-only mode with cached snapshots.
Diagnostic steps using browser devtools (no special permissions required; run in your own browser session):
- Open the Network tab, filter for WS, and locate the connection to
wss://trello.com/1/socket/<token>. - Inspect incoming frames; look for JSON payloads with a
typeof "board" and aseqfield. - After a manual page reload, note the
seqvalue sent in the client's resume message and compare it to the snapshot'ssinceSeqfield in the response. - Optionally, call the REST endpoint
GET /1/boards/{id}/actions?since=<lastAckSeq>(requires a valid API key and token) to verify that the delta log matches the WebSocket-delivered events.
Note that Power-Up iframes receive board updates via postMessage from the parent frame rather than directly via WebSocket, so their latency and ordering differ from the native UI. Mobile apps suspend and resume connections aggressively on background/foreground transitions, which affects presence accuracy.
Failure Modes
When a component degrades, the system follows defined fallback paths:
- Network partition – clients cannot reach the gateway; they fall back to long-polling HTTP for critical mutations (e.g., adding a comment). Real-time UI updates pause until connectivity is restored.
- Redis unavailability – the gateway can no longer store or retrieve connection state; it switches to read-only mode, serving cached board snapshots but rejecting new mutations.
- Gateway overload – CPU or network saturation triggers connection shedding; affected clients receive a close frame with retry guidance and are expected to reconnect with exponential backoff.
- Rate-limit trigger – a single connection exceeding the allowed mutation rate receives HTTP 429 responses on subsequent messages; the client should throttle its local optimistic updates.
These failure modes are observable via the operational checks above (e.g., a surge in HTTP 429 responses, increased latency, or a rise in reconnection attempts). Check the Atlassian status page for "Trello Real-time" component incidents that correlate with connection drops or latency spikes.
Conditions That Would Change the Design
The current architecture assumes:
- Board-level concurrency stays below the sharding limit of roughly 10k simultaneous users per board.
- Total ordering of mutations per board is required for correct UI state.
- WebSocket transport is available in all target environments (desktop browsers, mobile apps).
If any of these assumptions shift, the design would need revision:
- Higher concurrency – introducing board-level sharding or partitioning the event log across multiple Redis clusters, with a routing layer that directs connections to the appropriate shard.
- Relaxed ordering guarantees – moving to an eventually consistent model where clients apply mutations based on timestamps rather than sequence numbers, simplifying the catch-up logic but requiring conflict-resolution UI.
- Deprecation of WebSocket – adopting Server-Sent Events (SSE) or gRPC-web for server-to-client streams; the connection-state storage would remain similar, but the client-side reconnection handling would differ due to the unidirectional nature of SSE.
Revisiting the design under these conditions would involve re-evaluating trust boundaries (e.g., token scoping per shard) and updating operational checks to reflect the new failure domains. Note also that Atlassian's data residency regions (US, EU, AU) route WebSocket traffic to regional gateway clusters, so cross-region board access adds latency and may hit region-specific rate limits.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.