NestJS — clustering
The housed pool's second front door (Node ≥ 26): a dedicated listener where the main thread accepts TCP connections and hands each socket to a housed worker unparsed — no parsing, no proxy hop, no serialization on the API thread.
Wiring
// src/main.ts — cluster the housed pool onto its own listener (Node ≥ 26)
import { getAtollPool } from '@atolljs/nestjs';
import { createHttpCluster } from '@atolljs/node/http';
const pool = getAtollPool('housed');
if (pool) {
const transferPort = Number(process.env.TRANSFER_PORT ?? port + 1);
createHttpCluster({
pool,
port: transferPort,
onListen: () => log.log(`housed api (clustered) → :${transferPort}`),
});
// Below Node 26 the call logs a notice and returns null — no
// capability check needed.
}The worker side needs nothing — serveHttp in housed.worker.ts already accepts transferred sockets alongside its internal gateway port, so the same housed Nest app serves both entries.
Why a second port
Clustering routes per connection: the accepting thread never reads request bytes, so it can't split the app's port by URL path. /api/housed/* on the main port keeps using proxyToWorker (one origin for clients); the cluster listener is the zero-parse fast path for anything that can reach it.
Stickiness
A transferred socket pins for life, but separate connections round-robin — multi-connection session flows (socket.io's polling→upgrade, an HTTP call preceding a WS connection on the same worker) need route: stickyByAddress(), which hashes the client address onto a fixed worker. Details under Node.js → Clustering.
Live example
On Node ≥ 26, examples/nestjs serves the housed API clustered on :3101 — http://localhost:3101/api/housed/incidents/whoami answers with a worker's threadId while the API thread never touched the request.