Guide
How do I run 10 coding-agent tasks in parallel without them clashing?
Give each task its own machine. On one laptop, git worktrees give each agent its own copy of the files, but the agents still share your ports, databases, Docker and memory. With Sanbox, you list the tasks in a JSON file and sanbox batch starts each one in its own run, an isolated microVM with its own disk, so ten tasks can work side by side without touching each other.
Run this with your agent
Read https://sanbox.cloud/kb/parallel-work/run-coding-agent-tasks-in-parallel.md and follow it to run my tasks in parallel.
If the Sanbox CLI is missing, install it with `npm install -g @sanlabs/sanbox-cli@latest`
and sign in with `sanbox login`. Show me each command before you create, stop or delete a Computer.
Why do parallel agents clash on one machine?
Two agents in the same checkout overwrite each other's edits. Git worktrees solve that part: each worktree is a separate checkout on its own branch, sharing the repository's history. Claude Code automates this with claude --worktree <name>, and its docs note that each worktree is a fresh checkout, so you install dependencies in each one.
Worktrees isolate files, not the machine. Everything else is still shared:
- Two dev servers both want port 3000.
- Integration tests write to the same local database and the same Docker daemon.
- Ten agents compete for one laptop's CPU and memory.
- Every agent can reach whatever your laptop can reach, including your credentials.
| Git worktrees on one laptop | sanbox batch | |
|---|---|---|
| Files | One checkout per worktree | One disk per run |
| Ports and local databases | Shared | Separate in each run |
| Machine | Your laptop | One microVM per task |
| Network | Everything your laptop reaches | Only the hosts the template allows |
| Laptop can close | No | Yes, once every task is submitted |
| Cost | Free | Your Sanbox plan plus model tokens |
Worktrees are the right tool when two or three agents edit code and you review as they go. A batch suits independent tasks you want to hand off and collect later.
How do I write the tasks file?
Create .sanbox/tasks.json with one entry per task:
[
{
"task": "Review API idempotency and write output/api.md",
"external_run_id": "review-api-idempotency",
"input": ["app/"]
},
{
"task": "Inspect CLI input handling and write output/cli.md",
"external_run_id": "review-cli-inputs",
"input": ["cli/"]
}
]
taskis the instruction. Tell each task to write its results underoutput/. Inputs arrive under/workspace/input, and durable deliverables belong under/workspace/output.external_run_idis a stable ID for that task. If you run the same file again, Sanbox returns the existing run instead of starting a duplicate.inputlists relative paths to upload. Send only what the task needs. A bundle can hold at most 10,000 files and 64 MiB.
The CLI leaves out .git, node_modules, build output, .env files, private keys and common secret-like filenames by default. Add a .sanboxignore file for anything else that should stay on your machine.
Steps
1. Install the CLI and sign in
npm install -g @sanlabs/sanbox-cli@latest
sanbox login
sanbox auth check --json
2. Pick an OpenCode task template
A batch needs a task template: look for runnable: true and runner_config.execution_mode: "task" in the output of:
sanbox templates list --json
If there is none, an organisation admin can create one and validate it:
sanbox templates create --name "Parallel tasks" --type opencode-task \
--model-provider <provider-id> --model <model-id> \
--network-policy policy.json --json
sanbox templates validate <template-id> --json
3. Write the tasks file
Write .sanbox/tasks.json as shown above, with ten entries.
4. Start the batch
--max-parallel sets how many tasks the CLI submits at once:
sanbox batch --tasks .sanbox/tasks.json --template <template-id> \
--max-parallel 10 --wait --json
The CLI process does the fan-out, so keep it running until every task is submitted. With --wait it stays until every run ends, and exits with code 2 if any run failed.
How many runs are active at the same moment also depends on your organisation's run capacity. For larger fan-outs, talk to us.
5. Collect the results
The JSON output lists each run. For every run ID:
sanbox runs artifacts <run-id> --json
sanbox runs download <run-id> --output .sanbox/output/<run-id> --json
A task is done when its state is stopped, latest_execution.outcome is completed, and its files have downloaded.
6. Recover after an interruption
Run the same sanbox batch command again. The stable external_run_id values return the runs that already exist instead of starting new ones. To look around first, use sanbox runs list --json and sanbox runs get <run-id> --json.
Let Claude Code or Codex dispatch the batch
Your coding agent can write the tasks file and run the batch from your terminal. Save the Sanbox agent guide into the project so it knows the commands:
sanbox skill --write
This writes .sanbox/agent.md. Then ask your agent something like:
Read .sanbox/agent.md. Split the open review comments into independent tasks,
write .sanbox/tasks.json with a stable external_run_id per task, show it to me,
then run it with sanbox batch and download each run's output.
Keep SANBOX_API_KEY in the environment. Don't paste it into prompts, task files or inputs.
Lock down egress
Runs are deny-by-default. The task template's network policy should allow only the hosts the tasks need, such as your package registry:
{
"default_action": "deny",
"rules": [{ "destination": "registry.npmjs.org", "ports": [{ "from": 443, "to": 443 }] }]
}
Pass it with --network-policy policy.json when you create the template. A blocked request names the host it couldn't reach.
What this doesn't do
- Batch runs are one-shot OpenCode tasks. The agent inside each run is OpenCode, not Claude Code or Codex. To run Claude Code itself on a remote machine, use a Computer.
- No Docker in task runs. For tasks that need containers or a Compose stack, use a Docker Computer.
- Tasks don't talk to each other. Each run sees only its own inputs. Splitting the work and merging the results is up to you or your agent.
- Tasks return files, not commits.
.gitisn't uploaded by default, so results come back as files underoutput/. - No review. Sanbox runs the tasks. Read the output before anything reaches your main branch.
Related
- How do I try three approaches from the same starting point?
- How do I run Docker Compose inside an AI agent's sandbox?
- How do I restrict which domains an AI agent can reach?
- Persistent vs ephemeral sandboxes for AI agents
Sources
- Git, git-worktree documentation, checked 2026-11-06
- Claude Code, Run parallel sessions with worktrees, checked 2026-11-06