Reference
Environment and globals
Environment variables for pooled serve, the site's TURN relay and the test scripts, and the page globals a self-hosted deployment can set.
pooled serve
Section titled “pooled serve”| Variable | What it does |
|---|---|
POOLED_TOKEN |
Requires this token on every request, as Authorization: Bearer <t> or x-api-key: <t>. Kept out of the process list, unlike --token. --token-file wins over it. An empty value is an error. |
POOLED_KEEPALIVE_MS |
How often a waiting stream gets a keep-alive. For tests; the default is 10 s. |
POOLED_LEGACY_AUTH |
0: pooled host and the OpenClaw plugin’s host ignore the raw invite key from devices that run a Pooled from before channel-bound proofs (they wait for Allow) and refuse links that prove nothing. 1 (unsafe): pooled serve, pooled chat, pooled join and the plugin send their raw invite key to an older host, as before, instead of waiting for its Allow. Unset: hosts accept older devices for one release with a warning; clients never send raw keys. See Security model. |
Relay (pooled CLI)
Section titled “Relay (pooled CLI)”pooled host, pooled join, pooled chat and pooled serve connect directly when they can. When no direct path works (strict NAT or CGNAT on both ends, a network that blocks UDP), a link goes through a TURN relay: pooled.run’s by default, fetched with credentials that expire. See Use a TURN relay.
| Variable | What it does |
|---|---|
POOLED_RELAY |
0: no relay, direct links only. 1: every link goes through the relay (to test it, or to keep your IP address from the other devices). Unset: the relay is used only when no direct path works. |
POOLED_TURN |
Your own relay instead of pooled.run’s: turn:host:3478, turns:host:443?transport=tcp, comma-separated for several. Nothing is fetched then. |
POOLED_TURN_USER, POOLED_TURN_CRED |
The username and password for POOLED_TURN. |
POOLED_TURN_API |
Where to fetch relay credentials. Default https://pooled.run/api/turn; point it at a self-hosted deployment’s /api/turn. |
The client tools read their own variables. These are the ones the banner prints:
| Variable | Tool | Value |
|---|---|---|
OPENAI_BASE_URL |
OpenAI SDKs and tools | http://127.0.0.1:8080/v1 |
ANTHROPIC_BASE_URL |
Anthropic SDKs, Claude Code | http://127.0.0.1:8080 |
CLAUDE_CODE_MAX_CONTEXT_TOKENS |
Claude Code | the room’s context |
CLAUDE_CODE_MAX_OUTPUT_TOKENS |
Claude Code | a quarter of the context, at least 1024 and at most 32000 |
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC |
Claude Code | 1 |
OPENCODE_DISABLE_CLAUDE_CODE |
opencode | 1 |
See Connect your tools.
TURN relay (/api/turn)
Section titled “TURN relay (/api/turn)”Set in the Vercel project for api/turn.mjs, then redeploy. pooled.run sets the Cloudflare pair. With neither provider set, POST /api/turn answers 204 and rooms use direct links only.
| Variable | What it does |
|---|---|
TURN_KEY_ID |
Cloudflare Realtime TURN: the key’s Turn Token ID. Needs TURN_KEY_API_TOKEN. |
TURN_KEY_API_TOKEN |
Cloudflare: the key’s API Token. Mark it Sensitive. |
TURN_SECRET |
coturn in use-auth-secret mode: its static-auth-secret. Needs TURN_HOST or TURN_URLS. |
TURN_HOST |
coturn: the relay’s host name. Hands out turn:HOST:3478 over UDP and TCP and turns:HOST:443. |
TURN_URLS |
coturn: your own comma-separated turn: / turns: URLs, instead of TURN_HOST. |
TURN_TTL |
Credential lifetime in seconds, 600 to 86400. Default 21600 (6 h). |
TURN_RATE |
Credential requests per minute per IP, per function instance. Default 10. |
TURN_ALLOWED_ORIGINS |
Other origins allowed to ask, comma-separated; * matches within one host label. The deployment’s own origin is always allowed. |
If both providers are set, Cloudflare wins. Setup: TURN relay.
Page globals for self-hosting
Section titled “Page globals for self-hosting”Set these in p2p.html, before room.js loads. pooled.run sets none of them.
| Global | Default | What it does |
|---|---|---|
window.POOLED_SIGNAL_SERVERS |
["cloud"] |
Ordered signaling servers; the first that answers is used. Entries take the ?signal= forms, or { host, port, path, secure, key }. ?signal= wins over it. See Signaling servers. |
window.TURN_SERVERS |
none | RTCIceServer objects added after the public STUN servers, on top of a ?turn= or Network-box relay. When set, the page doesn’t ask /api/turn. See TURN relay. |
window.POOLED_TURN_ENDPOINT |
/api/turn |
Where the page asks for the site’s relay. On localhost only with ?turnapi=1. |
<meta name="preview-origin"> |
empty | The second site for Code mode previews (needed for run_js). See below. |
<script> window.POOLED_SIGNAL_SERVERS = ["wss://signal.example.com", "cloud"]; window.TURN_SERVERS = [{ urls: "turn:relay.example.org:3478", username: "pooled", credential: "SECRET" }];</script><meta name="preview-origin" content="https://pooled-preview.example.net">preview-origin takes a list separated by spaces or commas: host=origin entries apply to one page host (so one page can serve production and staging), a bare origin to any other. It must be https (plain http only on loopback), and an origin on the page’s own site is ignored with a console warning. Empty means previews run in the room’s tab without run_js; on localhost the other loopback name is used automatically.
Browser console
Section titled “Browser console”| Function | What it shows |
|---|---|
pooledDebug() |
Each peer link’s state: open channels, frames sent and received, keep-alives, duplicates, skipped frames, and whether it goes direct or through a relay (path, and via: udp, tcp or tls). swarmDebug() still works. |
pooledNet() |
This tab’s relay (relay, and from: yours, site or default for /api/turn) and whether UDP gets out of this network (udp). |
Tests and benchmarks
Section titled “Tests and benchmarks”For working on Pooled itself. See Testing.
| Variable | Used by | What it does |
|---|---|---|
WEIGHT_CACHE |
Deno tests and benchmarks (tests/weight_cache.js) |
Where the converted-weights cache lives. Default ~/.cache/swarmllm-weights. 0 or off turns it off. |
WEIGHT_CACHE_VERIFY |
same | 1 also checks each entry’s checksum, at about 1.5x the warm load time. |
WEIGHT_CACHE_PRUNE |
same | 1 deletes cache directories from older loader versions. |
ROOM_FLAGS |
Deno tests and benchmarks | The room’s URL switches as a query string, for example ROOM_FLAGS="kv=q8" or "fuse=0". Unset: exactly what the room runs. See URL options. |
STRICT |
tests/run.sh |
1 also fails a test that prints SKIP. |
MODEL |
benchmarks/bench.js |
qwen (Qwen3 0.6B, the default) or q38 (Qwen 3.8 27B). |
TOKENS |
benchmarks | Decode tokens to time. Default 32. |
MODEL |
tests/bench_ctx.js |
moe (the default) or 27b. |
FILLS, CTX |
tests/bench_ctx.js |
Context fills to time (default 1K, 8K, 32K) and the engine’s context in tokens (default: the room’s default, raised to hold the largest fill). |
KV |
tests/bench_ctx.js |
f16 (the default) or q8, the same as the room’s ?kv=q8. |
HW, DATE |
tests/bench_ctx.js |
Labels for the bench-log rows it prints, for example HW="GB10" DATE="Sep 29". |
WEIGHT_CACHE=0 tests/run.sh q38cd tests && MODEL=moe KV=q8 HW="GB10" DATE="Sep 29" \ deno run --unstable-webgpu --allow-read --allow-env --allow-write=$HOME/.cache/swarmllm-weights bench_ctx.jsEngine test scripts read more kernel-tuning variables (BCOLS, MOE_FUSE, PREFILL_UBATCH and others), listed in each script’s header comment.