How We Scaled Our Real-Time Sync Engine to 10M Concurrent Users
When we first built Flowdesk's real-time collaboration, we handled maybe 10,000 concurrent connections. Last month, we hit 10 million. Here's the story of how we got there — and every painful lesson along the way.
The Early Days: WebSockets and Prayer
Our v1 sync engine was beautifully simple. A single WebSocket server, an in-memory document state, and operational transforms to handle concurrent edits. It worked great until about 50,000 users, at which point everything caught fire.
Enter CRDTs
We migrated to Conflict-free Replicated Data Types in late 2024. CRDTs guarantee eventual consistency without a central coordinator, which meant we could finally distribute our sync layer across multiple regions.
The key insight was choosing the right CRDT for each data structure. We use a tree-based CRDT for rich text, a last-writer-wins register for metadata fields, and a grow-only set for tags and labels.
Edge-Optimized Routing
The real breakthrough came when we moved our WebSocket routing to the edge. Instead of all connections hitting a central cluster, we now maintain sync nodes in 40+ regions. When you open a Flowdesk document in Tokyo, your WebSocket connects to a node in Tokyo — not Virginia.
Conflict Resolution at Scale
At 10M concurrent users, conflicts aren't edge cases — they're the norm. We built a three-tier resolution strategy: client-side prediction for instant feedback, server-side CRDT merge for consistency, and a background reconciliation pass that catches any drift.
The result: median sync latency of 47ms globally, with 99th percentile under 200ms. Not bad for a system that started as a single Node.js process.