Gil Allouche
← All writing
ReferenceAutonomous agents

Self-hosted AI coding agents: what to actually run

Self-hosting the agent loop and self-hosting the model weights are two different purchases. Here is what each one costs you, and which one I'd skip.

October 25, 2026·Gil Allouche·11 min read
A reference explainer. Every factual claim links to its source; where this is an opinion from operating experience, it says so.

The short answer

OpenHands ships under MIT, runs its agent loop inside a Docker container you control, and will point at any OpenAI-compatible endpoint (repo, docs). That one fact contains the distinction most people miss when they search for this: a self-hosted AI coding agent is two independent decisions — where the agent loop runs, and where the model weights run — and for almost everyone the right split is to self-host the loop and keep calling a hosted frontier model.

Self-hosting the loop gets you a step cap you own, an audit trail, a sandbox boundary, a scheduler, and no per-seat bill. Self-hosting the weights gets you one thing — your code never leaves your network — and costs you the model quality the loop depends on. Different purchases. Price them separately.

I took Metadata.io from $0 to $15M ARR and I'm now building a company where the agents do the work, so my bias is toward anything that runs unattended and leaves a log.

The two layers, drawn

The two layers of a self-hosted coding agent: the loop you host and the model you rent or ownLayer 1 — you host thisRepo checkoutAgent loopExec sandboxStep + cost capLayer 2 — rent or ownHosted frontier APILocal vLLM / OllamaSame API shapeThe cap is enforced in your code, not in the prompt.

The right-hand swap is a config change — both vLLM and Ollama expose OpenAI-compatible endpoints (vLLM docs, Ollama). The left-hand side is where all the engineering lives. Same point I made about orchestration being a control layer, not a framework: the loop, the cap and the sandbox are yours regardless of which model you call.

The tools, and what each one actually is

Licenses and architecture, not marketing categories. "Loop runs in" is the column that decides whether you can schedule it.

ToolLicenseLoop runs inUnattended modePoints at local weights
OpenHandsMITIts own Docker runtime containerYes — CLI / headlessYes, any OpenAI-compatible endpoint
SWE-agentMITDocker, one container per instanceYes — built for batch benchmark runsYes, via LiteLLM
AiderApache 2.0Your shell, inside the repoScriptable (--message, Python API)Yes — Ollama and OpenAI-compatible
GooseApache 2.0Your shell or desktop appCLI with recipesYes
ClineApache 2.0VS Code extension hostNoYes
ContinueApache 2.0IDE extensionNoYes
Codex CLIApache 2.0Your shellYes — codex execConfigurable providers
Gemini CLIApache 2.0Your shellYes — non-interactive flagVendor-hosted model

Two things fall out of that table.

Codex CLI and Gemini CLI are both Apache-2.0 open-source clients, and the license of the client tells you nothing about where inference happens. When someone says they're "self-hosting Codex," ask which of the two layers they mean. It is usually neither.

SWE-agent and OpenHands are the only two here designed from the start around running with nobody in the chair. SWE-agent came out of the SWE-bench work and exposes a per-instance cost limit as a first-class flag, because it was built to run hundreds of instances at once without burning a credit card. OpenHands exposes max_iterations in its config. Those two settings are the difference between an agent and a toy.

What you can actually fit on a GPU

This part is arithmetic, which means nobody gets to argue about it. Weight memory is roughly parameters × bytes-per-parameter: about 0.5 bytes per parameter at 4-bit quantization (llama.cpp GGUF formats), about 1 byte at 8-bit, about 2 at bf16.

ModelParametersLicenseWeights at 4-bitWhat that lands on
Qwen2.5-Coder-32B-Instruct32.5B denseApache 2.0~16.3 GBOne 24 GB card, ~8 GB left for KV cache and activations
Devstral Small 250524B denseApache 2.0~12 GBSingle RTX 4090 or a 32 GB Mac, per the model card
Qwen3-Coder-480B-A35B-Instruct480B total, 35B activeApache 2.0~240 GBFour 80 GB cards before you've allocated a single token of context

Run Qwen2.5-Coder-32B at bf16 instead and you need ~65 GB — a single 80 GB card or two 48s. The MoE routing on Qwen3-Coder-480B saves you compute, not memory; all 480B parameters still sit in VRAM. Devstral was tuned for agentic use with OpenHands, has a 128k context window, and its card reports 46.8% on SWE-bench Verified.

Then there's the context ceiling, which is where self-hosted coding agents quietly fall over. Qwen2.5-Coder-32B's card lists 32,768 tokens native, extendable to 131,072 with YaRN. A coding agent on a real repository eats 32k in a handful of turns: file contents, diffs, test output, stack traces, and the full prior conversation re-sent every turn. Deploy at the native 32k window without configuring the extension and the agent starts forgetting what it changed four steps ago. You will diagnose that as a reasoning failure. It isn't. It's truncation.

And on the scores: SWE-bench Verified is 500 human-validated samples from the original SWE-bench set (OpenAI). A percentage on it measures model-plus-harness on Python repositories that already have tests. It does not measure how your agent handles your TypeScript monorepo. Aider publishes a separate, reproducible code-editing leaderboard (leaderboards), and the ordering is not always the same. Read two benchmarks or none.

What the hosted API side actually costs

Do this arithmetic before you buy a GPU. You need to know what you're replacing.

A single agent run on a real ticket is long. Turns stack, and each turn re-sends the accumulated history plus whatever files got read. The numbers below are a scenario shape, not a measurement — a 40-turn run at roughly 15k input and 1.5k output tokens per turn, across 5,000 runs. Replace all four with your own and watch the total move.

What would this cost you?
40
15,000
5,000
per run
$2.70
full pass
$13,500

Arithmetic on published list prices. Retries are billed too, so a step that fails twice before working costs three times this.

Two corrections to whatever number you just got.

Prompt caching cuts it hard, because an agent's input is mostly a prefix it already sent — the system prompt, the repo map, the earlier turns. Cached input tokens bill at a discount (OpenAI prompt caching). Reorder the prompt every turn and you lose the cache, and the bill goes back up. Stable prefix first, volatile content last.

The other correction runs the other way. Failed runs cost full price. An agent that takes 40 turns to not fix the bug bills the same as one that fixes it in 12, which is why SWE-agent's per-instance cost limit and OpenHands' max_iterations matter more than the per-token price.

Compare that total against a GPU that sits idle nights and weekends, plus the engineer-hours to keep vLLM, the model weights and the quantization pipeline current. For teams under fifty engineers the hosted API wins on cash and wins harder on attention. If your code genuinely cannot leave the network, the comparison doesn't apply and you buy the GPU — but say that out loud as a compliance decision, not an economics one.

Sandboxing, which is the part people skip

A coding agent's job is to run shell commands. That's the whole value and the whole problem.

Docker is the default boundary for OpenHands and SWE-agent, and it's a reasonable default. Containers share the host kernel, which Docker's own security docs say plainly (Docker engine security). There are two specific ways people turn that reasonable default into no boundary at all.

The first is mounting the Docker socket into the agent container. Access to /var/run/docker.sock is root-equivalent on the host, and an agent that can start containers can mount your root filesystem. This gets mounted all the time, so the agent can "run the test container."

The second is long-lived cloud credentials in the sandbox env. The agent reads its own environment. So does every dependency it installs. Scope the credentials to the one repo and expire them with the run.

If the agent is executing code from sources you don't control — a PR from outside, a dependency it chose to install, an issue body it decided to follow — container isolation is the wrong tier. gVisor interposes a user-space kernel; Firecracker gives you a microVM per run. Both exist precisely because people needed to execute untrusted code, and both predate the agent wave.

Prompt injection belongs here, not in a safety appendix. A coding agent reads repository files, issue text, dependency READMEs and CI output, and all of that is untrusted input to a model holding tool permissions. It's the first entry in the OWASP Top 10 for LLM Applications (OWASP). The mitigation that holds up isn't better prompt wording. It's that the agent's credentials can't do the damaging thing in the first place.

The failure modes that show up in production

These are documented and general, across harnesses and models. None are exotic.

Unbounded loops. The agent retries the same failing command with cosmetic variations until something stops it, and this is the single most common way an unattended run becomes an unattended bill. The fix is a step cap and a cost cap enforced in your code, outside the model — not an instruction in the system prompt asking it politely to give up. Both OpenHands and SWE-agent ship this. If you write your own loop, write the cap first.

Context exhaustion. Described above. Symptom: the agent re-reads a file it already read, or reverts its own earlier edit. Instrument tokens-per-turn and alarm on the slope, not just the total.

Tool-call malformation under load. Smaller open-weight models degrade on structured tool calls before they degrade on prose, especially deep into a long trajectory with many tools in scope. JSON parse errors at turn 25 and not turn 3 are the signal. Fewer tools in scope is a bigger lever than a bigger model.

Silent no-op. The agent reports success, the diff is empty or touches only a comment. Gate on git diff --stat and on the test suite exit code, never on the agent's own summary of what it did.

Non-determinism between runs. The same ticket twice produces two different patches. That's expected behaviour, not a bug, and it breaks any workflow that assumed reproducibility. Pin the model version, log the full trajectory, and treat each run as an independent proposal that a test suite accepts or rejects.

Tool connection is solved. MCP is the common protocol, Goose is built on it, and the major clients speak it. Tool selection is not solved — an agent with thirty tools in scope picks worse than an agent with six.

What I would not use

An IDE extension as the unattended substrate. Cline and Continue are good at what they're for, and what they're for is a human watching. The loop runs in your editor's extension host, on a laptop that sleeps, with no scheduler and no durable trajectory log. If you want work to happen on a cron or on a webhook, you need a headless runner. Use the extension for supervised work and a separate headless harness for everything else — different products that happen to share a model.

Self-hosted weights as the first move. Self-host the model on day one and every harness bug looks like a model bug, every model limitation looks like a harness bug, and you spend a month not knowing which. Get the loop, the cap, the sandbox and the merge gate working against a hosted frontier model first. Then swap the endpoint and measure what you lost. The swap is a config change; doing it in that order is what gives you a baseline to compare against.

An agent with push access to the default branch. Branch and pull request, every time, with CI as the gate. Human review on the diff, not on the agent's description of the diff.

Spend authority. Opening a PR, running a test suite and filing an issue are reversible actions — each one lands in front of a CI gate or a reviewer before it changes anything. I would not let one approve its own merge or provision infrastructure that bills. That's a judgement about where the review step belongs, and it's the same judgement behind shipping one capped agent rather than a fleet: the cap is the product decision, not the guardrail you add afterwards.

Sources

  1. OpenHands (All-Hands-AI) repository — MIT license, Docker-based sandboxed runtime, headless/CLI mode
  2. OpenHands documentation — Runtime sandbox configuration, max_iterations limit, LLM provider configuration
  3. SWE-agent repository — MIT license, agent-computer interface, per-instance cost limit flag, batch runs
  4. Aider repository — Apache-2.0 license, terminal pair programmer, local and OpenAI-compatible model support
  5. Aider LLM leaderboards — Published, reproducible code-editing benchmark across models
  6. Cline repository — Apache-2.0 VS Code extension; agent loop runs in the editor extension host
  7. Continue repository — Apache-2.0 IDE assistant, configurable to local model providers
  8. Goose (Block) repository — Apache-2.0 agent, MCP-based extensions, CLI
  9. OpenAI Codex CLI repository — Apache-2.0 client with non-interactive exec mode and configurable model providers
  10. Gemini CLI repository — Apache-2.0 open-source client to a hosted-only model
  11. Qwen2.5-Coder-32B-Instruct model card — 32.5B parameters, Apache 2.0, 32,768 native context extendable to 131,072 with YaRN
  12. Devstral Small 2505 model card — 24B parameters, Apache 2.0, 128k context, SWE-bench Verified score reported by Mistral, single-GPU claim
  13. Qwen3-Coder-480B-A35B-Instruct model card — 480B total / 35B active parameters — basis for the VRAM arithmetic
  14. Introducing SWE-bench Verified (OpenAI) — 500 human-validated samples; what the benchmark actually measures
  15. vLLM documentation — OpenAI-compatible inference server for self-hosted weights
  16. Ollama repository — Local model serving with an OpenAI-compatible endpoint
  17. llama.cpp repository — GGUF quantization formats behind the bytes-per-parameter arithmetic
  18. Docker engine security — Containers share the host kernel; docker socket access is root-equivalent
  19. gVisor documentation — User-space kernel sandbox for untrusted workloads
  20. Firecracker microVM — MicroVM isolation used for multi-tenant untrusted code execution
  21. Model Context Protocol — Open protocol for connecting agents to tools
  22. OWASP Top 10 for LLM Applications — Prompt injection as a documented application-layer risk class
  23. OpenAI prompt caching guide — Cached input tokens are billed at a discount, which changes agent economics

Related