A definitive collection of production-grade architectural patterns for WebSockets. Stop guessing how to handle reconnects, scaling, and dropped packets—use these battle-tested concepts.
Sponsored by Stackaura & Ahmar Hussain
Engineering real-time architectural solutions for global applications.
The initial WebSocket connection is easy: new WebSocket('ws://...').
Maintaining that connection in production is hard. Load balancers drop idle connections. Mobile devices lose signal. Users open multiple tabs. Servers need to be scaled horizontally but WebSockets are stateful.
This repository, curated by Ahmar Hussain and the engineering team at Stackaura, serves as an architectural cookbook to solve these exact problems.
Each pattern below includes a dedicated folder with runnable code examples (Node.js backend, Vanilla JS / React frontend).
How to implement a true exponential backoff algorithm with jitter to prevent the "Thundering Herd" problem when your server restarts.
Stale connections are the silent killer of server memory. Learn how to implement bi-directional pings to cull "zombie" connections reliably.
When a user disconnects for 5 seconds on a train, how do you catch them up on the messages they missed without sending the entire historical dataset?
WebSockets are stateful. If User A connects to Server 1, and User B connects to Server 2, how do they chat? We demonstrate integrating a Redis Pub/Sub backplane.
If a user has 10 tabs open to your app, you shouldn't have 10 open WebSocket connections. Learn how to use the BroadcastChannel API or SharedWorkers to multiplex a single WS connection across tabs.
A sneak peek at the reconnection logic from Pattern #1:
class ResilientSocket {
constructor(url) {
this.url = url;
this.reconnectAttempts = 0;
this.maxReconnectDelay = 10000; // 10 seconds
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onclose = () => {
// Exponential backoff: 2^attempts * 1000
let delay = Math.pow(2, this.reconnectAttempts) * 1000;
// Add 'Jitter' to avoid thundering herd
const jitter = Math.random() * 500;
delay = Math.min(delay + jitter, this.maxReconnectDelay);
console.log(`Reconnecting in ${delay}ms...`);
setTimeout(() => this.connect(), delay);
this.reconnectAttempts++;
};
this.ws.onopen = () => {
console.log('Connected!');
this.reconnectAttempts = 0; // Reset counter on success
};
}
}Have you solved a unique real-time streaming problem?
- Fork the repo.
- Add your pattern to a new folder.
- Ensure it runs independently.
- Submit a PR.
This project is licensed under the MIT License - see the LICENSE file for details.
Created and maintained by Ahmar Hussain and Stackaura. Building real-time futures.