···416416await listen(app.server, ...args);
417417```
418418419419+Options:
420420+421421+```ts
422422+serverThreads(run.workers, server, {
423423+ balance: leastConns(), // or roundRobin(); default: leastConns()
424424+ highWaterMark: 64, // per-worker cross-thread buffer (default 64)
425425+ listen: { drainTimeout: 30_000 }, // per-worker drain budget on shutdown
426426+});
427427+```
428428+429429+`highWaterMark` bounds how many fds are in-transit to each worker's MessagePort at once. When a worker can't keep up, the cross-thread pipe parks until it catches up.
430430+419431Graceful shutdown: call `server.close()` on the main listener; the cascade closes worker channels, drains in-flight requests (up to `drainTimeout`, default 30s), and resolves the moroutines. Combine with `await using run = workers(...)` for full pool teardown.
432432+433433+See [`examples/server-threads`](examples/server-threads) for a runnable demo.
420434421435## Streaming
422436
+24
examples/server-threads/main.ts
···11+// Scale an HTTP server across worker threads using fd-fanout.
22+// Requires Node v24+ and a POSIX system (Linux, macOS).
33+//
44+// Run: node examples/server-threads/main.ts
55+// Test: curl http://localhost:3000
66+77+import { createServer } from 'node:net';
88+import { workers, assign } from '../../src/index.ts';
99+import { serverThreads } from '../../src/serve/index.ts';
1010+import { runServer } from './server.ts';
1111+1212+const server = createServer();
1313+server.listen(3000);
1414+1515+process.on('SIGINT', () => server.close());
1616+process.on('SIGTERM', () => server.close());
1717+1818+console.log('Listening on http://localhost:3000 with 4 worker threads');
1919+2020+{
2121+ await using run = workers(4);
2222+ using threads = serverThreads(run.workers, server);
2323+ await run(threads.map(([w, args]) => assign(w, runServer(...args))));
2424+}
+11
examples/server-threads/server.ts
···11+import { createServer } from 'node:http';
22+import { mo } from '../../src/index.ts';
33+import { listen, type ListenArgs } from '../../src/serve/index.ts';
44+55+export const runServer = mo(import.meta, async (...args: ListenArgs): Promise<void> => {
66+ const srv = createServer((req, res) => {
77+ res.writeHead(200, { 'Content-Type': 'text/plain' });
88+ res.end(`handled by worker ${process.pid}\n`);
99+ });
1010+ await listen(srv, ...args);
1111+});