1. Prepare the environment
Install the task’s dependencies and fixtures in one sandbox. Then save it under a name:- Use one named snapshot per environment version:
task-env-v1,task-env-v2. A named snapshot does not change after you save it. - Docker images: a named snapshot keeps only the images that a container uses. Run
docker create --name keep-<x> <image>for each image. See What a snapshot saves. - 10 named snapshots are free. Each one more costs $1.70 a month. See Named snapshots.
2. Run episodes in parallel
This Python script starts one sandbox per episode from the named snapshot, runs the episode, reads the score and deletes the sandbox. It paces the starts to the minute limit of the $20 plan.run_episodes.py
exec_commandwaits at most 600 seconds. For a longer episode, start it withdetached=Trueand pollcommand_status. See Python SDK.ttl_seconds=3600stops a sandbox after one hour if your script crashes before the delete.- In asyncio code, wrap each call in
asyncio.to_thread. The SDK is synchronous.
Fork instead of a named snapshot
boat fork <id> (or fork in the API) also copies a sandbox. Use it to branch one episode mid-way, for example to try several actions from the same state.
- A fork copies the newest snapshot of its source. If the source keeps running, later forks get later states.
- A fork of a running sandbox uses its last background snapshot. Files written after it can be missing. Stop the source first for an exact copy.
Limits
- On the $20 plan, the hour limit (60) sets the pace: 100 episodes take about 100 minutes to start. On the $100 plan (210 per hour), they take about 29 minutes. The day limit caps a long run.
- A start above the limit fails with
429 rate_limited, names thewindow, and does not count. The API sends noRetry-Afterheader. - An organization multiplies these numbers by its seats.
--fail-fast(fail_fast=True) answers in about 1.5 seconds when no machine is free, instead of waiting.
Cost
Boat bills each second that a sandbox runs. A deleted sandbox costs nothing.
Model calls are extra when an agent runs in the sandbox. See Pricing and AI credentials.
Agents in the episode
To run Claude Code, Codex or another harness in each sandbox, send a prompt to the sandbox and wait for it. See Integrated agents and Python SDK. To keep your model keys out of the sandboxes, use the AI credentials proxy. For episodes that other people or untrusted code control, create the sandboxes withno_env=True. They then get none of your secrets.
Harbor and Terminal-Bench
- Harbor runs on Boat through the Harbor adapter (
harbor run -e harbor_box_environment:BoxEnvironment). - Terminal-Bench 2.0 does not run through that adapter today. Each of its tasks names a prebuilt Docker image, and the adapter refuses tasks with a Docker image.
- To run a Terminal-Bench style task on Boat now, install its dependencies in a named snapshot (step 1) and run the task’s test script with
boat exec.