OpenHands — A Deployment Notebook
A working engineer's notebook on deploying OpenHands, the open-source coding agent that grew out of OpenDevin, against a real codebase. The runtime topology, the model adapters, the gotchas, and the production-readiness ledger.
OpenHands — the project formerly known as OpenDevin — is the open-source coding-agent project that has come closest, in our 2025 reading, to being a credible standalone alternative to the closed coding agents. The project’s repository is at All-Hands-AI/OpenHands, the All Hands AI team has been shipping weekly releases, and the model coverage is the broadest of any open-source coding agent we have deployed. This piece is a deployment notebook from a recent engagement: what we shipped, what we hit, and the production-readiness ledger we ended the week with.
We are not benchmarking OpenHands against Claude Code or Cursor. The comparison is interesting but is a different piece. We are writing here about what it takes to put OpenHands in front of a working engineer on a real codebase, and what the project’s production characteristics actually are.
The runtime topology
OpenHands runs as a server-plus-runtime. The server (Python, FastAPI under the hood) holds the agent state. The runtime is a Docker container that the agent operates inside — running shell commands, editing files, executing tests. The decoupling matters; the runtime is what gets blown away and re-created between sessions, and it is also the boundary at which OpenHands keeps the agent from touching the host system.
The reference deployment is a docker-compose-shaped setup with the OpenHands server on the host and the runtime in a sibling container, sharing a workspace volume. For the engagement we wrote this notebook against, we deployed against a customer’s existing codebase with the workspace mounted from the customer’s repo checkout. The runtime image (docker.all-hands.dev/all-hands-ai/runtime:<version>) is published per OpenHands release. Pinning to a specific runtime version was, for us, load-bearing.
The agent loop lives in the server. The agent picks an action — a shell command, a file edit, a browse, a finish — and the runtime executes it. Results come back to the server. The agent picks the next action. Most of the visible production behavior is a function of that loop’s stopping criteria, the model’s grounding in the workspace state, and the runtime’s responsiveness.
Model adapters
OpenHands supports a broad set of model providers through LiteLLM. We ran the engagement primarily against Claude Sonnet 4 (via the Anthropic API) and ran the comparison against gpt-4o and gpt-4.1. The model swap is configured in config.toml and is a one-line change. The agent prompt is the same across providers, which has the predictable effect: Anthropic’s models follow the action vocabulary more cleanly, OpenAI’s models are more aggressive about completing the task with fewer turns, and the open-weight models we tested (deepseek-chat-v3, Llama-3.1-70B-Instruct) handle the easy cases and struggle with the multi-file editing patterns.
The model-cost question matters. A single non-trivial OpenHands session on Claude Sonnet 4 — a feature added to a 50k-LOC repo, with a passing test suite at the end — cost roughly $3-$6 in inference at the published 2025 prices. Multiply by the number of sessions and the cost becomes a real planning item. For the engagement, we set a per-session token budget in the OpenHands config (max_iterations, max_budget_per_task) and let the agent know about it. The result was tighter sessions and a small but real degradation in completion rate on the longer tasks.
What we shipped
Across the week, we deployed OpenHands against four use cases on the customer’s codebase:
-
Bug-fix sessions on tickets the customer’s engineers had labeled as straightforward. OpenHands closed seven of ten without intervention. The three that needed intervention failed on issues that required understanding the customer’s deploy pipeline, which the agent did not have access to.
-
Test-coverage extension on a module with 40% line coverage. OpenHands wrote 130 new tests across two sessions, of which 110 passed on the first run and 20 needed adjustments — usually because the test was correct but the underlying module had latent bugs the agent had not been asked to fix.
-
A small refactor — extracting a logging concern into a separate module. The agent did the refactor cleanly. It also took 40 minutes and burned through more inference than the customer’s senior engineer would have. This is the case where OpenHands’ economics did not yet pay off.
-
A documentation pass — writing missing README sections for an undocumented subsystem. OpenHands shipped solid drafts. The customer’s engineers edited them down to publication quality in roughly 30% of the time the from-scratch draft would have taken.
What we hit
The gotchas we hit, in approximate order of operational pain:
The runtime versioning gotcha. We pinned the runtime image to a known-good version. We did not, initially, pin the server version. A mid-week server upgrade changed the action vocabulary in a way the pinned runtime did not fully support, and the agent’s str_replace_editor calls started silently failing on multi-line edits. The fix was to pin both. The lesson is to pin both.
The BrowsingAgent rate-limit gotcha. OpenHands ships several agent types. The default CodeActAgent is well-suited to the use cases above. The BrowsingAgent, which we used briefly for a “go read this internal wiki and summarize” task, hit the customer’s corporate proxy in a way that triggered the proxy’s rate limiter and got the OpenHands container’s IP temporarily blocked. The fix was to give the runtime its own outbound proxy with a request budget. The lesson is that browsing agents have a different operational footprint than coding agents.
The repo-size gotcha. OpenHands’ default workspace-mount pattern works cleanly for small-to-medium repos. The customer’s monorepo is on the larger end (1.2 GB checkout, large node_modules, large vendor directory). The runtime container booted slowly, the find and grep calls the agent issued were expensive, and the agent’s spatial sense of the codebase was poor. We mitigated this with a workspace subset — mount only the directory the agent was working in — and with a custom repo_map.md we generated and dropped in the workspace root. Both helped. The lesson is that a 1+ GB monorepo deserves a workspace-subset story before you put an agent against it.
The state-leak gotcha. Between sessions, the runtime container is rebuilt. Between turns within a session, it is not. We had two cases where the agent edited a file, the test suite passed, and the next turn picked up state — an environment variable, a half-applied migration — that the agent had not declared. The fix was a stricter “reset between tasks” discipline in the runtime configuration. The lesson is that any agent runtime with mutable state needs a reset story you actively manage.
The production-readiness ledger
Our subjective state-of-the-project read after the engagement:
OpenHands is production-credible for:
- Bug-fix sessions on well-defined tickets in repos under ~500k LOC.
- Test-writing on modules with clear input/output contracts.
- Documentation drafts.
- Boilerplate generation against a clear spec.
OpenHands is not yet production-credible for:
- Cross-system changes that touch the deploy pipeline, the secret manager, or the customer’s identity layer. The runtime does not have credentials to these systems and the agent does not know that it does not.
- Long-horizon refactors that span more than two or three commits. The agent loses track of the cross-commit invariants and produces work that does not compose cleanly.
- Customer-facing UI work where visual correctness is the success criterion. The agent does not see the rendered UI.
The split is not unique to OpenHands. It applies, with small variations, to every other coding agent we have run. The reason it matters specifically for OpenHands is that the open-source positioning — the project’s pitch is “self-host, model-agnostic, no vendor lock-in” — only pays off if the production envelope is wide enough to handle the work the team actually wants to ship. Our reading is that the envelope is wider than the closed-source incumbents’ marketing wants to admit, and narrower than the open-source enthusiasts want it to be.
A working summary
OpenHands is one of the more serious open-source coding agents in the 2025 field. It deployed cleanly against a real customer codebase in a week. It produced work that, for the right shape of task, justified its inference cost. The production-readiness ledger above is the honest one: where the agent shines, where the agent fails, and what the operational overhead looks like.
We will keep deploying OpenHands at engagements where the customer’s risk model accommodates open-source self-hosting, where the codebase fits the project’s current envelope, and where the team has the operational maturity to manage the runtime as if it were a small production service. That is more engagements than the open-source-coding-agent conversation usually credits, and fewer engagements than “OpenHands is a drop-in replacement for Cursor” would imply. The truth, as usual, is between the marketing and the eulogy.
Related reads
Retrieved 2026-06-12 — Permalink: https://agentic.review/articles/openhands-deployment-notebook/
The Agentic Review · agentic.review