Co-build sandbox iteration speed: where the seconds actually go
When you co-build an app with an AI inside a sandbox, one iteration has four costs. Three of them are bounded and small. The fourth is the model. Here is the honest budget, with file paths so you can check the math.
On a warm sandbox claimed from the pool, the framework overhead per iteration is about 2 seconds (the ACP session/new call), plus a sub-second git commit at the end. On a cold boot you also pay ~2.5 seconds for the firecracker VM start. Everything else in the wall clock is the model writing tokens. The numbers come from comments at src/core/e2b.ts:7 and src/core/e2b.ts:2641 and are mirrored by the e2b.acp.session_new log event.
The four costs in one iteration
A co-build sandbox iteration starts when you submit a prompt and ends when the preview shows the change and the new SHA is at the head of the version stack. Between those two points, the framework pays for four things, in this order:
Per-iteration cost breakdown
- VM boot, ~2.5 seconds. E2B firecracker microVM starts from the pre-baked template. Skipped entirely on a pool claim.
- ACP session/new, ~2 seconds. Spawns the agent subprocess and initializes its working directory. The cost prewarm targets.
- Model token generation. Whatever Claude takes to read the prompt, plan, and stream the edits. Bounded by the route's 800-second ceiling.
- Commit at end of turn, sub-second. git add -A and git commit inside /app on the small project trees these sandboxes hold.
“When a project picks up a pool sandbox, the sandbox is already booted, we only pay the session/new cost (~2s).”
src/core/e2b.ts, line 2641
The handshake, top to bottom
The shape of one iteration looks like this: the route serializes against the sandbox lock, claims or boots a VM, calls into the ACP bridge to stream the model, then commits. The bridge is what makes the sandbox usable by an agent at all; it is a small HTTP API running inside the VM that fronts the Claude subprocess. The reason session/new is the hotspot is that it is where the agent subprocess actually gets spawned with the right credentials.
One iteration on a warm pool sandbox
What a cold start log actually looks like
When the pool is empty and the route has to boot fresh, the timing shows up in the structured logs as discrete events. This is the sequence printed by flog in src/core/e2b.ts on a cold path. Pay attention to the order: VM start comes before the ACP bridge can be reached, and the bridge has to be alive before session/new can return.
On a warm path, the first two lines disappear. The route still blocks on the model and still commits at the end, but boot and session are gone. That is the practical meaning of pool warmth: the two framework-shaped costs collapse to one cheap step.
Things that look like framework cost but are not
A few wall-clock items get blamed on the sandbox when they actually come from somewhere else.
- npm install mid-turn. If the agent decides to add a package, npm fetches and links it inside the sandbox. This is the single biggest non-model cost in practice and can add tens of seconds. It is not framework overhead; it is the agent choosing to install something. Prompts that stay inside the existing dependency tree do not pay this.
- Vite full reload vs HMR. Small JSX edits hot-patch in under a second. Changes to vite.config, the index.html scaffold, or anything Vite cannot hot-patch trigger a full reload of the preview iframe. The model wrote the change quickly; the renderer is taking the time.
- Residential IP back-pressure. When residential IP is enabled, browser traffic from the sandbox goes through brd-proxy.js at 127.0.0.1:3003 inside the VM before reaching the upstream. If the upstream is slow or rotating sessions, page navigation in the preview can drag even though the app code itself was generated quickly.
How to keep iteration tight in practice
None of these are tricks. They are just the consequences of the cost breakdown above.
- Stay on the same sandbox. Closing the tab and reopening does not kill the sandbox if the session persists in Firestore, but a fresh anonymous session (different localStorage key) pays the full cold boot. Sign in to keep the same session.
- Avoid dependency churn. Tell the agent which library you want, or let it commit to one early. Every later npm install adds latency you cannot get back inside the same turn.
- Prefer small focused prompts. The model is the dominant cost, so shorter turns finish sooner. You can chain three two-second edits faster than waiting for one six-second omnibus.
- Use undo instead of re-prompting when you change your mind. Undo skips the model entirely; the only time cost is whatever Vite takes to render the restored files.
Want a deeper look at the iteration loop?
If you are evaluating co-build sandboxes for a team or a product, I am happy to walk through the timing trace on a call.
Frequently asked questions
What counts as one iteration in a co-build sandbox?
One iteration is one user prompt round-trip: you type a change, the agent edits files inside the sandbox, the preview re-renders, and the change is committed. In mk0r the closure of that round-trip is marked by a real git commit. The function `commitTurn` in src/core/e2b.ts runs `git add -A && git commit` in /app after the agent finishes streaming, so 'iteration N is done' means a new SHA at the head of the stack. Anything that happens before the commit is part of the same iteration; anything after is the next one.
How long does a fresh sandbox take to boot?
About 2.5 seconds for the VM itself. That number is a comment at the top of src/core/e2b.ts and matches what we see in the logs (event name `e2b.acp.session_new` records the second piece). The template is pre-baked, so npm install, the ACP bridge, Chromium, and the Vite scaffold are all already on disk. The 2.5s is mostly E2B firecracker startup. After that the code pays for `session/new` against the ACP bridge, which is the second cost item.
What does the warm pool actually save?
The pool saves the boot. Line 2641 of src/core/e2b.ts says it directly: when a project picks up a pool sandbox, 'the sandbox is already booted, we only pay the session/new cost (~2s)'. The pool is a Firestore-backed list of sandboxes that have already finished startup.sh and are sitting at idle. When a new co-build session opens, it claims one of those, writes /run/mk0r-session.json into it, and runs `session/new` against the ACP bridge to get a fresh conversation. That is the difference between a cold start (boot + session) and a warm start (session only).
Why is session/new the 'hotspot that pre-warming eliminates'?
The comment at src/core/e2b.ts:2462 calls session/new the hotspot. It is the slowest single step in the cold path that is not the model itself, because the ACP bridge has to spawn the agent subprocess with credentials and initialize its working directory. Pre-warming runs this exact step in advance, on a sandbox in the pool, so the cost is paid before any user types anything. The user-facing first iteration on a pool claim does not pay it at all; it pays only the much cheaper claim-and-write step.
How fast is the second iteration onward?
Model-bound, almost entirely. The ACP session created on prewarm is long-lived, so subsequent turns reuse it. Each follow-up prompt goes to /session/prompt with the same sessionId; the agent does not re-init, does not re-read the project from scratch, and does not redeploy anything. The wall clock from 'submit' to 'preview updated' is dominated by how long Claude takes to write tokens plus however long Vite's HMR takes to apply the diff. The framework overhead at the boundary is a fetch and a commit.
How long does the commit at the end of a turn actually take?
A few hundred milliseconds on a small project. `commitTurn` runs `git add -A` and `git commit` against a local-only repo inside the sandbox (no remote push). The repo lives on the sandbox's filesystem, the working tree is tiny (a Vite + React scaffold plus whatever the agent generated), and most turns change only a handful of files. The commit itself rarely shows up as a bottleneck in the per-turn timing.
What stretches the wall clock past the model's own latency?
Three things, in roughly this order. First, npm install if the agent decides to add a dependency mid-turn; that is the longest non-model item and can add tens of seconds. Second, the preview iframe re-render, which depends on Vite HMR for small edits or a full reload for changes Vite cannot hot-patch. Third, network back-pressure from the proxy if residential IP is on, since browser traffic goes through brd-proxy.js at 127.0.0.1:3003 before reaching the upstream. For a normal edit-no-deps turn, none of these fire and the wall clock is just model tokens.
What is the route's hard timeout on a single iteration?
800 seconds. Read it at src/app/api/chat/route.ts (the top of the file declares the route's max duration). That is the ceiling: if the model takes longer than ~13 minutes to write a single turn, the route is cut. In practice we have not seen a real iteration get close; the per-turn budget is designed to absorb large refactor turns without ever being the limiting factor for normal edits.
Does undo cost the same as a forward iteration?
Cheaper, because no model tokens. Undo and revert in mk0r are git operations against the in-sandbox repo. `jumpToSha` and `revertToSha` in src/core/e2b.ts do `git checkout <sha> -- .`, then `git add -A`, then a new commit with --allow-empty if needed. The agent is not consulted; the bytes on disk are walked. From a user perspective, the iteration speed of undo is whatever Vite takes to re-render the now-restored files. Forward iteration always has to wait on the model; undo never does.
Related guides
AI app builder iteration past the first generation
Per-turn git commits, fork-on-undo, persistent ACP session. The full iteration mechanism mapped to source.
How good are current AI app makers at iteration
First-draft generation looks impressive across tools. The interesting question is what happens at turn three.
Vibe coding feedback loop iteration
The shape of the iteration feedback loop when you describe instead of code.
Comments (••)
Leave a comment to see what others are saying.Public and anonymous. No signup.