Horizontal scaling confirmed: real-time state not held solely in process memory
Why it matters
Storing presence, channel subscriptions, or message history exclusively in process memory means that restarting a single server instance silently resets that state for all users connected to it. In production, auto-scaling and rolling deploys trigger instance restarts routinely — users are dropped from channels, presence shows them offline, and in-flight message queues are lost. ISO 25010 reliability requires that state survival is not contingent on any individual process's uptime.
Severity rationale
Low because in-process-only state loss occurs on restart or scale events — a failure mode that is invisible in development but routine in production deployments.
Remediation
Externalise real-time state to a shared backend. The Socket.IO Redis adapter handles presence and room membership automatically; use a database or Redis for message history.
import { createAdapter } from '@socket.io/redis-adapter';
import { createClient } from 'redis';
const pub = createClient({ url: process.env.REDIS_URL });
const sub = pub.duplicate();
await Promise.all([pub.connect(), sub.connect()]);
io.adapter(createAdapter(pub, sub));
// Rooms, presence, and subscription state now survive instance restarts
For message history, write to the database on send and query on reconnect — never rely on an in-process buffer as the source of truth. The skip condition applies only when the deployment contract explicitly states single-instance forever.
Detection
-
ID:
horizontal-scaling-ready -
Severity:
low -
What to look for: Enumerate all real-time state storage locations: in-process Maps, Redis, Memcached, database tables. Count the state types stored externally: presence, message history, subscriptions, channel membership.
-
Pass criteria: Real-time state (presence, message history, subscriptions) is stored in at least 1 shared backend (Redis, Memcached, database), not only in process memory. At least 2 state types must be externally persisted.
-
Fail criteria: Real-time state exists only in process memory. Horizontal scaling would lose state when instances restart.
-
Skip (N/A) when: The deployment is explicitly single-instance and not expected to scale.
-
Detail on fail:
"Presence state stored in process memory only. Adding a second server instance would lose user presence data." -
Remediation: Use a shared state backend for horizontal scaling:
import { createAdapter } from '@socket.io-redis'; import { createClient } from 'redis'; const pubClient = createClient(); const subClient = pubClient.duplicate(); io.adapter(createAdapter(pubClient, subClient)); // Now presence, rooms, and other state are shared across instances
External references
- iso-25010:2011 · reliability.availability — Availability — real-time state survives instance restart and horizontal scale events
Taxons
History
- 2026-04-18·v1.0.0·Initial import from community-realtime·automated