Preview
OpenClaw
Use Pooled as an OpenClaw model provider. The OpenClaw gateway becomes a device in a room, holds its share of the layers, and other machines, tabs and phones hold the rest. Start a room or join one with its invite link.
OpenClaw is a self-hosted agent: a gateway process on your machine runs the agent loop and its tools (exec, read, edit, …) and calls a model provider for every step. The @pooled/openclaw plugin adds Pooled as that provider.
When you pick Pooled, the OpenClaw gateway itself becomes a device in a Pooled room. It holds its share of the model’s layers on the local GPU and runs them with Pooled’s own engine, on Dawn (npm webgpu) inside the gateway’s Node process. Other devices join the same room and hold the rest:
- another machine with the plugin, or with
pooled join; - a browser tab or a phone with the room’s invite link.
So a model none of the devices can run alone serves the agent, with no API key and no cloud model.
OpenClaw gateway (Spark) Mac Studio iPhone (optional) ┌───────────────────────────┐ ┌──────────────┐ ┌──────────────┐ │ agent loop + tools │ │ pooled join │ │ Safari, │ │ @pooled/openclaw │ WebRTC │ Node + Dawn │ WebRTC │ pooled.run │ │ room node: embed, layers │ <------> │ layers 19-39 │ <------> │ 1-2 layers │ │ 0-18, head, checkpoints │ │ (Metal) │ │ │ └───────────────────────────┘ └──────────────┘ └──────────────┘OpenClaw’s requests and tool calls take the same path as pooled serve: the room’s host renders the chat template, constrains tool calls with a grammar and parses them. The host also keeps OpenClaw’s system prompt and each turn as checkpoints, so each step reads only its new tokens.
Install
Section titled “Install”You need Node 22 or newer (OpenClaw ships on 24), OpenClaw 2026.9.6 or newer, and a GPU that Dawn runs on: Linux with glibc 2.38 or newer and a Vulkan driver, macOS 26 or newer, or Windows with an NVIDIA GPU (Direct3D 12).
openclaw plugins install clawhub:@pooled/openclawopenclaw onboard # Model/auth provider -> More... -> Pooled- Or from npm:
openclaw plugins install @pooled/openclaw. - OpenClaw shows the plugin’s capabilities and asks you to accept them;
--accept-capabilitiesskips that. webgpu(Dawn, about 95 MB) is an optional dependency. If it didn’t install, the gateway says how to add it when it needs the GPU.
From a checkout
Section titled “From a checkout”git clone https://github.com/Nehanth/pooled.git && cd pooled/packages/openclawnpm install && npm packopenclaw plugins install ./pooled-openclaw-0.3.1.tgz --force --accept-capabilitiesStart a room
Section titled “Start a room”In openclaw onboard, pick Pooled → Start a room on this device, then:
- Say how much of this GPU’s memory to lend.
- Pick the model. Each one shows whether it’s downloaded, its download size, the memory it needs across the room and its context. The Qwen3.6 35B MoE is preselected; see Which model.
- If it isn’t downloaded, pick Download now, Download when the gateway starts or Don’t download (stream this machine’s layers at each start).
- Pick how many devices to wait for, and who can join: Devices with the invite link or Anyone with the room code.
Onboarding prints the room code (4TK-G9P) and the invite link (https://pooled.run/r/4TKG9P#k=…). The room opens when the gateway starts and keeps its code and link across restarts. On your other devices, do one of these:
- Open the invite link in Chrome or Safari.
- Run
npx @pooled/cli join "<invite link>". - Pick Join a room in OpenClaw there and paste the link.
Join a room
Section titled “Join a room”In openclaw onboard, pick Pooled → Join a room, paste the invite link (or type the code) and say how much memory to lend. Onboarding connects right away:
- With the invite link, the device is let in at once.
- With the code alone, it shows
Waiting for <host> to let this device in…until the host allows it.
It keeps the pass the host gives it, so the gateway gets straight back in after every restart. It also learns the host’s model and context window.
The room needs at least a 16k context, because OpenClaw’s own instructions and tools are about 12k tokens. pooled host qwen3-1.7b opens at 16k from @pooled/cli 0.3.2; with 0.3.0 or 0.3.1 its host should run pooled host qwen3-1.7b --ctx 16384. A room whose memory is short for 16k (under about 5.5 GB across the room) opens the 1.7B at 8k instead, on the room page, in pooled host and in the plugin’s own room: the plugin then warns that OpenClaw needs 16k, and onboarding says fits on this machine alone at 8k (OpenClaw needs 16k). Onboarding warns when a joined room’s context is shorter.
Which model
Section titled “Which model”Use the Qwen3.6 35B MoE (about 23 GB across the room). Onboarding preselects it when this device’s memory holds it, the Qwen3.8 27B (about 20 GB) when only that fits, and the MoE again when neither fits on this device alone (the room then waits for more devices). A device that joins with pooled join (@pooled/cli 0.4.0 or newer) on a discrete GPU can make up a short room by keeping some of the MoE’s experts in system RAM, more slowly (MoE experts in system RAM). The gateway itself holds its layers whole. The Qwen3.5 122B MoE is in pooled host and pooled pull from 0.4.0, not in OpenClaw’s onboarding.
Measured on a DGX Spark, the OpenClaw gateway hosting and a second device (pooled join) holding the other half of the layers, OpenClaw 2026.9.6:
| Turn | Qwen3.6 35B MoE (128k context) | Qwen3 1.7B (16k context) |
|---|---|---|
| First question after the room came online | 143 s (OpenClaw’s whole prompt, cold) | 163 s |
| Second question in the same chat | 4.6 s (17k tokens reused) | 119 s (nothing reused) |
| “Read notes.txt and tell me the secret word” | 10.4 s (2 model calls) | 25.8 s (5 model calls) |
| The same in a new session | 21.2 s | 580 s: 85 tool-search calls, then OpenClaw stopped the loop with no answer |
| OpenClaw’s background memory save | not triggered | on almost every turn; holds the room for about 120 s |
The 1.7B gets OpenClaw’s file tools only (read, write, edit, ls). For a small model, onboarding also offers (off unless you pick it) to turn off OpenClaw’s tool search (tools.toolSearch = false) and its memory flush (agents.defaults.compaction.memoryFlush.enabled = false). Both are global OpenClaw settings: they apply to every model and agent, not only Pooled, and stay when you switch models. Undo them with openclaw config unset tools.toolSearch and openclaw config unset agents.defaults.compaction.memoryFlush.enabled.
Let devices in: /pooled
Section titled “Let devices in: /pooled”In any OpenClaw chat (the TUI, the Control UI, a messaging channel), the gateway’s owner can run:
| Command | What it does |
|---|---|
/pooled |
Shows the room: invite link, devices, whether they hold the model, who is waiting to join |
/pooled allow |
Lets the first waiting device in (/pooled allow 2, /pooled allow all) |
/pooled deny |
Turns it away |
/pooled link |
Prints the invite link |
/pooled pledge 12 |
Lends another amount of this machine’s GPU memory |
Models
Section titled “Models”Models are kept in ~/.pooled/models, the same folder as pooled pull, so each is downloaded once per machine. Downloads resume and are checked against their SHA-256. A hosting gateway downloads a missing model in the background while devices join; a question meanwhile says how far it is.
Config
Section titled “Config”Onboarding writes plugins.entries.pooled.config. Each key can be overridden by its variable:
| Key | Variable | Meaning |
|---|---|---|
mode |
POOLED_MODE |
host or join |
code |
POOLED_CODE |
The room code |
| — | POOLED_LINK |
A room’s invite link, to join (non-interactive setup) |
model |
POOLED_MODEL |
The model a host starts |
pledgeGB |
POOLED_PLEDGE_GB |
GPU memory this device lends |
minDevices |
POOLED_MIN_DEVICES |
Devices to wait for before dealing the layers (default 1) |
ask |
POOLED_ASK |
Host: a device with the code alone waits for /pooled allow (default on) |
pull |
POOLED_PULL |
Host: download a missing model (default on) |
prewarm |
POOLED_PREWARM |
Host: warm up OpenClaw’s system prompt and tools when the room comes online (default on) |
allowApiClients |
POOLED_ALLOW_API |
Host: answer other devices’ API asks (default on) |
modelDir |
POOLED_MODELS |
Models folder (default ~/.pooled/models) |
waitSeconds |
POOLED_WAIT_S |
How long a question waits for devices or the host’s model (default 120) |
ctx |
POOLED_CTX |
Context to ask for (default: the model’s largest) |
name |
POOLED_NAME |
This device’s name in the room |
signal |
POOLED_SIGNAL |
A PeerServer host:port (default: the PeerJS cloud server pooled.run uses) |
Non-interactive setup: openclaw onboard --non-interactive --auth-choice pooled with POOLED_MODE=host, or with POOLED_LINK="<invite link>" to join.
The invite key and the passes are kept in ~/.openclaw/pooled/room.json (mode 0600), never in openclaw.json.
Room problems show in the OpenClaw chat as ⚠️ Pooled: …: waiting for the host to let this device in, waiting for devices, not enough memory, downloading, a device left while it held layers, the host doesn’t allow API clients, the host runs an older Pooled. The model never sees them. When the conversation outgrows the room’s context, OpenClaw compacts it and asks again.
Results
Section titled “Results”Qwen3.6 35B MoE (Q4_0, about 20 GB), 128K context, OpenClaw 2026.9.7 with its full tool profile. Five tasks, each in a new session, each checked by a script the agent never sees:
- answer a question by reading files;
- a code edit;
- run the tests and fix the code;
- add a feature with tests;
- summarize a 140 KB (about 33K-token) file.
No tool call in any run was malformed or came back as an error.
| Room | Layer split | Passed | First call (cold) | Decode |
|---|---|---|---|---|
| A: OpenClaw on the Spark, Mac joins | Spark 0-18 + head, Mac 19-39 | 4/5 | 61.8 s (17.4K tokens) | 17-29 tok/s |
| A2: A with turn checkpoints | same | 5/5 | 61.7 s | 16-30 tok/s |
| B: OpenClaw on the Mac, Spark joins | Mac 0-18 + head, Spark 19-39 | 4/5 | 49.2 s (14.5K tokens) | 17-32 tok/s |
| C: A plus an iPhone 14 Pro Max in Safari | Spark 0-17, iPhone 18-19, Mac 20-39 | 4/5 | 89.2 s | 9-16 tok/s |
- After the first call, each task’s first model call reads 4-8 s of prompt: the system prompt comes from a checkpoint.
- With turn checkpoints (A2), the four short tasks took 55-139 s and the long file 306 s.
- Every failure is the same model mistake on the edit task: it printed
$-12.34instead of-$12.34, said it was fixed and never checked. In A2 the model tested its change and passed. - The phone held its 2 layers through a 23-minute run and roughly halved the speed. A phone should get layers only when the computers can’t hold the model.
Turn checkpoints. OpenClaw drops each call’s trailing context block from the next call, so in a tool loop the host’s cache never matched past the system prompt. The host now also saves a checkpoint where the last user turn starts. From A to A2: the long file went from 813 to 306 s, the feature from 298 to 139 s, the tests from 119 to 57 s.
Per-task tables are in docs/openclaw-poc.md.
Limits
Section titled “Limits”- Cold first call. The first call after a gateway starts reads OpenClaw’s whole prompt (14-18K tokens): 49-64 s on two computers, 89 s with a phone. A hosting gateway replays the last system prompt and tools when its room comes online, so that read happens before the first question. Each device keeps its part of the pinned system prompt and tools on disk (
~/.pooled/cache/ckpt/), so after a restart the room reads it back; answer and turn checkpoints live in GPU memory only. - Decode over the network. Two computers over Wi-Fi decode at 25-30 tok/s; the Mac alone does about 92. Splitting pays one network hop per token, so it is for models that don’t fit on one device.
- Browser hosts have no turn checkpoints yet, so OpenClaw joined to a room hosted in a tab re-reads more per tool call.
- Checkpoint memory isn’t part of the layer split. At 50K tokens one checkpoint is about 1 GB across the room for the MoE, and the host keeps up to 8 (4 pinned, 4 answer or turn).
- Small models (the 1.7B) are slow with OpenClaw and loop on tool search; see Which model. The MoE is the model to use.
- Windows (Direct3D 12) is tested on an RTX 5070 with the gateway hosting the room. Only NVIDIA GPUs have been tried there. With OpenClaw 2026.9.8 on Windows, the Control UI’s chat works only at
/chat/main.
Who can see and steer what
Section titled “Who can see and steer what”- Getting in. A hosted room asks before new devices join: the invite link gets a device in, a code alone waits for
/pooled allow, and a device you let in keeps a pass. With Anyone with the room code, anyone who has or guesses the code gets in. - Proofs, not keys. From plugin 0.3.0 and CLI 0.4.0, devices prove the invite key or pass on each link instead of sending it, and the host proves it back. A device waiting for
/pooled allowshows a six-digit code that the gateway’s log shows beside its request; if they match, nobody sits in the middle. A device on an older Pooled is markedan older Pooled: it can't prove the invite key. See Who is on a link. - Screens. A hosting gateway opens its room so the other devices’ room pages show “answering…” stand-ins, never OpenClaw’s prompts, answers or tool calls.
- Devices holding layers see the conversation anyway. Each one gets the hidden state of every token, which carries the prompt (the files OpenClaw read, the tool results). A device holding layers can also send back any hidden states it likes. That lets it choose the model’s output, including the tool calls OpenClaw then runs on the gateway machine. The call grammar only keeps the calls well formed.
- Join mode trusts the room’s host with everything. It sends OpenClaw’s whole context to the room’s host and runs the tool calls it gets back.
- Guests can ask their own questions, which queue with OpenClaw’s requests. Turn
allowApiClientsoff to keep API clients out.
See also Rooms from the terminal, which uses the same headless room node, and Privacy.