Sub-Socket Model
The sub-socket is the core scaling unit of the Micro Socket methodology: one logical subscription group per topic, enabling millions of concurrent broadcasts with predictable resource usage.
Server: Millions of Sub-Sockets and Broadcast
The gateway maintains a sub-socket (subscription group) per topic or channel. When a message is published, only clients in that topic’s sub-socket receive it. Physical connection count is secondary; subscription count is the scale unit.
Scale unit
- Scale unit: number of subscriptions (sub-sockets), not number of TCP connections.
- A broadcast targets only the sub-socket for that topic; other topics are untouched.
- Millions of sub-sockets can exist with controlled memory and CPU (e.g.
Map<topic, Set<connection>>).
Client: Same Idea
The client can follow the same micro design:
- Single-purpose connections: e.g. one micro socket for prices, one for risk alerts, one for payment notifications.
- Benefits: fault isolation, different QoS/retry per channel, different ACL/tokens.
Sub-Socket Data Structure (Server)
Represent sub-sockets as topic → set of connections. Each connection tracks its subscribed topics for cleanup.
// topic -> Set<WebSocket | connection handle>
const topicSubscribers = new Map();
function addSubscriber(conn, topic) {
if (!topicSubscribers.has(topic)) {
topicSubscribers.set(topic, new Set());
}
topicSubscribers.get(topic).add(conn);
}
function removeSubscriber(conn, topic) {
const set = topicSubscribers.get(topic);
if (set) {
set.delete(conn);
if (set.size === 0) topicSubscribers.delete(topic);
}
}
function removeConnection(conn) {
if (conn.topics) {
conn.topics.forEach((t) => removeSubscriber(conn, t));
}
}Sub-Socket Lifecycle (Server)
- Idle: connection open, no subscriptions (or all unsubscribed).
- Active: at least one topic subscribed; client receives broadcasts for those topics only.
- On close, remove the connection from every topic set to avoid leaks.
Broadcast Flow
When the backbone (or an internal publisher) emits a message for a topic:
- Look up
topicSubscribers.get(topic). - If empty, skip.
- Otherwise, serialize the message once and send to each connection in the set (only if connection is still open).
See Gateway: Sub-Socket & Broadcast for full code, and Elysia Example for a complete ElysiaJS implementation.