Every few months someone builds a system that runs an army of coding agents, and the first question is always whether you can point it at your own hardware instead of a metered API. Gas Town, an open-source multi-agent orchestrator first tagged in January 2026, answers that question in its own source code, in a preset almost nobody reads. It runs Claude Code, so we pointed Claude Code at a local model on a Mac, and then measured what the agent actually sends before it does a single useful thing: 29,424 tokens, of which 74 percent by size is tool definitions. For a team choosing between the two, we also priced that turn at Anthropic’s published rates.
Measured on 20 August 2026 on our test machine (an M4 Pro with 48 GB, LM Studio, gemma-4-31B-it-QAT at Q4_0 with a 65,536-token context) with Claude Code CLI 2.1.153. The current release is 2.1.283; the tool count and sizes below are for the build we ran.
The short version is that the local path works and the arithmetic is brutal. Both halves matter, and the second half is the one nobody publishes.
Can Claude Code run on a local model?
Yes, and Gas Town ships the proof rather than the documentation.
Reading internal/config/agents.go in the Gas Town repository turns up a preset called groq-compound. Its comment explains the mechanism plainly: the Claude binary acts as an SDK proxy, and the preset overrides the base URL, API key and model name at spawn time to send traffic somewhere other than Anthropic.
ANTHROPIC_BASE_URL -> https://api.groq.com/openai/v1
ANTHROPIC_API_KEY -> $GROQ_API_KEYThe preset’s own note is the interesting part: because the transport is still the Claude binary, every Gas Town hook, session tracker and lifecycle event works exactly as it does on the standard preset. Nothing downstream knows the difference.
Swap that host for a local one and the same trick points at your own machine. There is no mention of Ollama, LM Studio or a user-facing base-URL setting anywhere in the repository, so this is a capability rather than a feature. It works because of how the redirect is built, not because anyone documented it for local use.
Two things have to be true for it to work, and both took a measurement to establish.
The first is that the server has to speak the Anthropic protocol, not just the OpenAI one. LM Studio does: a POST to /v1/messages with an anthropic-version header returns a proper content block, and with "stream": true it returns correct message_start and content_block_delta events. That is the wire format the Claude binary expects.
The second is the URL itself, and this one wastes an afternoon if you get it wrong. Set ANTHROPIC_BASE_URL to http://127.0.0.1:1234/v1 and the CLI appends its own path, producing /v1/v1/messages. LM Studio answers that with HTTP 200 and an error body, which the CLI reports as “API returned an empty or malformed response (HTTP 200)”, followed by advice to check for a proxy or gateway intercepting the request. There is no proxy. The status code is a success, the body is a complaint, and the error message sends you looking in the wrong place. Drop the /v1 and it connects.
What does a coding agent send before it does anything?
We put a logging proxy between the CLI and LM Studio to capture the exact request bodies, because the interesting number is not what the model returns but what it has to read first.
One claude -p invocation with a single short prompt produced three requests totalling 149,989 bytes. The large one breaks down like this:
| Part of the request | Size | Share |
|---|---|---|
| Tool definitions (28 of them) | 96,040 chars | 74% |
| System prompt | 26,831 chars | 21% |
| Messages | 7,636 chars | 6% |
That is the finding. The agent’s own instructions are the small half. Three quarters of the payload is machine-readable schemas describing 28 tools, most of which any given turn will never call, and all of which are re-sent on every request that carries them.
Our first reading of this was wrong, and the correction is worth stating because it is easy to make. LM Studio rejected the initial attempt with request (29424 tokens) exceeds the available context size (8192 tokens), and we recorded that as the size of the system prompt. It is not. It is the whole request, and the capture shows the system prompt is barely a fifth of it. An error message told us a true number about the wrong thing.
The tool block is the part the tool ships. The context files an agent loads are the part a user writes and can edit, and we counted those separately, below. On these measurements the tool block is the larger of the two per request.
How many tokens do an agent’s context files add?
We counted four real files, the ones our agents actually load, on 17 August 2026. The count came from the tokenizer of the model being run, gemma-4-31B-it-QAT, by reading usage.prompt_tokens off the completions endpoint rather than estimating from characters.
| File | Size | Tokens | Bytes per token |
|---|---|---|---|
SOUL.md, the agent’s persona | 5,085 B | 1,230 | 4.1 |
AGENTS.md, the workspace guide | 7,059 B | 1,897 | 3.7 |
hermes-agent/AGENTS.md | 75,142 B | 20,007 | 3.8 |
| skills prompt snapshot, JSON | 47,098 B | 15,788 | 3.0 |
The rule of thumb that four bytes make a token holds for prose markdown and breaks for structured data. The JSON skills manifest packs a token into every three bytes, because punctuation, braces and quoted keys tokenise far denser than English does. Estimate a JSON context file at four bytes per token and you will be about 25 percent under.
Added together the four files are 38,922 tokens. That is 475 percent of an 8,192-token context window, and 119 percent of a 32,768-token one. At 8K context both large files returned HTTP 400 rather than a completion, because the request could not be tokenised into the window. We reloaded the model at 32K to get their counts, and even then they fit only individually, never together.
In memory, at the 80 KB per token this model’s KV cache costs, SOUL.md occupies 96 MB, the workspace guide 148 MB, the large agent file 1,563 MB and the skills manifest 1,233 MB: 3.0 GB of RAM for all four, spent before any work happens. In time, the 20,007-token file took 329.1 seconds to process cold and the 15,788-token file took 260.7, which works out at 60.8 and 60.6 tokens a second, in line with the roughly 65 tokens a second we measured for cold prompt processing. The four files together are about 599 seconds, just under ten minutes, on a cold cache.
In an ordinary session that cost is paid once. llama.cpp reuses the KV cache for any matching prompt prefix, and a system prompt sits at the front of every request and does not change between turns, so after the first message it is a prefix hit. The corollary is where it hurts: anything that changes the front of the prompt, such as a timestamp, a rotating session id or a reordered tool list, invalidates everything after it and turns 599 seconds once into 599 seconds every turn. Put volatile content at the end of the prompt, never the beginning. The Claude Code run below is a case where the prefix reuse did not hold, for a reason we have not yet found.
Two things follow for a team. Measure each file with the tokenizer of the model you run, because character estimates disagree most on the structured files that tend to be largest. Then ask of each block whether it is useful on every turn, not whether it is useful. The single 20,007-token reference file accounts for 1,563 MB of cache and 329.1 seconds of cold processing; moved into a file the agent reads on demand, it costs nothing until the moment it is needed, and the read itself is a few hundred tokens. If each agent session holds its own copy of the cache, two sessions with the same full context load hold 6.0 GB between them (2 times 3.0 GB). Whether LM Studio shares one cached prefix across sessions we have not measured, so that is the upper case, and the test with two and three concurrent sessions is on our list. Three gigabytes is also roughly what a second model resident alongside the first costs on this machine.
The counts are gemma-4’s tokenizer. A model with a different vocabulary will produce a different number for the same file, usually within about 10 percent for English prose but further out for dense JSON, so re-count rather than carry these figures to another model. And these are four files from one setup, not a survey of agent context files in general.
What does it cost to run one turn locally?
Eight minutes, for one line of output.
The model was gemma-4-31B-it-QAT at Q4_0, loaded at 65,536 context because 8K is not enough to hold the request at all. Two runs of the same trivial prompt:
| Run | Cache state | Wall clock |
|---|---|---|
| 1 | cold | 8 min 10 s |
| 2 | warm | 7 min 40 s |
Both sent byte-identical payloads of 149,989 bytes. The reply in each case was three words.
The second run is the one that surprised us. On this machine, repeating a prompt normally collapses prompt processing to almost nothing, because llama.cpp reuses the KV cache for any matching prefix. Here it bought six percent, and the capture timestamps show the large request itself was no faster on the second run; the saving came from the small follow-up call. We did not establish why, and will not guess at it in print: the payload is identical byte for byte, so something inside the request is defeating the prefix match, and identifying it needs another experiment. What we can say is that the caching behaviour which rescues ordinary local chat does not rescue this workload.
The rough arithmetic is consistent with our earlier measurements without matching them exactly. Cold prompt processing on this machine runs at about 65 tokens a second, so roughly 34,000 tokens of request across three calls predicts something in the region of eight to nine minutes, which is what the clock showed. We are not claiming a precise fit. Three requests, partial cache effects and a larger context window than the original benchmark all sit between the estimate and the stopwatch.
Then there is memory. At 65,536 context the backend process held 25.17 GB, which lines up with the 80 KB per token we measured for this model’s KV cache. One agent, one model, one context window, and a 48 GB machine is already more than half committed.
Gas Town’s README says it scales to 20 to 30 agents. Our two-model test on the same hardware showed that concurrent generation converges on about 9 tokens a second per model, because the GPU time-slices. Dozens of agents on one Mac is not a tuning problem. It is arithmetic.
Claude Code local model or Anthropic API: what a turn costs a dev team
For a development team the comparison is a turn on hardware it owns against a turn billed by the token. Our measurement gives the local side directly. One turn took 8 minutes 10 seconds cold and 7 minutes 40 seconds warm, and the large request in it was 29,424 tokens. Run back to back, one Mac completes fewer than 60 such turns in an eight-hour day (480 minutes divided by 8 minutes 10 seconds is about 58.8), and with 25.17 GB held by one agent’s model and context, it serves one agent at a time.
The API side is arithmetic on the vendor’s published prices, Anthropic’s list as read on 17 October 2026. Claude Sonnet 5.5 is listed at $2 per million input tokens, $0.10 per million for cache hits and $10 per million output tokens. At those rates the 29,424-token request costs about $0.059 with nothing cached and about $0.003 when the whole prefix is a cache hit, and a three-word reply adds almost nothing. Claude Opus 5.5, at $4 per million input tokens, doubles the uncached figure to about $0.118. Our count used Gemma 4’s tokenizer, and Claude’s tokenizer counts the same text differently, so these are estimates of the order of cost, not a quote.
Over a month the arithmetic runs like this. A Mac’s full capacity at this workload, about 58.8 turns a day over 22 working days, is about 1,293 turns. The same number of turns on Sonnet 5.5 would cost about $76 uncached (1,293 times $0.059) and under $4 with the prefix cached (1,293 times $0.003). One Mac at this workload serves one agent at a time, and our two-model test showed the GPU time-slicing between models when a second ran.
We have not sent the same Claude Code turn to Anthropic’s API and read the billed input, cache and output tokens, so the dollar figures are our local token count priced at the list rates, not a measured cost per turn. That run is on our list.
The context files counted above add to both bills. Those four files were 38,922 tokens: about 599 seconds of cold prompt processing on our test machine, paid once per session, or about $0.078 per uncached request on Sonnet 5.5 at the same list price.
Is Beads worth running on its own?
This is the part we would actually use, and it needs no model at all.
Beads is the work ledger underneath Gas Town, shipped as a separate MIT-licensed binary. It has more stars than the orchestrator it was built for, which tells you how many people arrived for the memory and left the agents behind. It runs completely offline.
The mechanism is a dependency graph over a work queue. Create four tasks and all four are open. Declare that the writing depends on the audit, the card depends on the writing, and publishing depends on the card, and bd ready returns exactly one item: the audit. Close it, and the queue advances by itself. Close the next, and it advances again.
That is the whole trick, and it is aimed squarely at the thing that breaks agent fleets. A coding agent’s context ends when its session ends. Thirty agents in parallel have thirty separate amnesias. Beads keeps the plan outside all of them, in a .beads/ database (embedded Dolt by default) with a JSON export carrying status, priority and a dependencies array so an agent can ask what is startable and get a definitive answer instead of re-reading a plan document and guessing.
One thing to know before running it in a real repository: bd init writes AGENTS.md and CLAUDE.md into your project root alongside the .beads/ directory.
The honest summary of a day with both is that the orchestrator is a bet on cheap inference and the ledger is not a bet at all. Beads costs nothing to run, works with any agent or none, and solves a problem you have whether or not you ever start a second agent. Gas Town on local hardware works exactly as advertised, and the eight-minute reply is the argument against it.



