Skip to content

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.

javascript
// 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:

  1. Look up topicSubscribers.get(topic).
  2. If empty, skip.
  3. 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.

Star the repo on GitHub if this documentation is useful — link in the navbar above.