Skip to main content
At the end of this page, you have tried several approaches to the same task at once and kept the best one. You set up one machine with the repo, tools, and sign-ins, and copy it into a few machines. An agent or a script works in each copy, and you compare the results. Every copy starts with the same disks, so nobody repeats the setup.
1

Set up one machine

my-repo, npm ci, and npm test on this page stand for your own repo and its commands.
exec prints the command’s output when the command exits.
2

Fork it

This command makes try-1, try-2, and try-3 with the same template and size, and waits until they run. One command makes up to 5 copies. With --json, it prints the new machines under machines. Without it, it prints their rows and the time the fork took.The disks are copied on the machine’s host in a few seconds, without a snapshot. Memory and running programs are not copied. The source machine is not changed. Copies of one source wait for each other only while their disks are copied, then boot in parallel.
3

Run one approach in each

approach-a.sh to approach-c.sh stand for your own scripts.
Each exec --background prints the ID of the job it started. jobs ls lists the jobs of a machine. With a coding agent, run instabox agent prompt try-1 -f "..." in each copy. See Coding agents.
4

Compare the copies and keep one

pull copies the copy’s dist folder to ./dist-b on your computer. The rm commands delete the copies you do not keep.
Each copy is a machine. It counts toward your plan’s machines and machine starts a minute, and fork waits out the start limit. Each copy also runs: when your workspace cannot run --count more machines, fork creates none and says how many fit. See Limits.

Start copies from a snapshot instead

A snapshot keeps the setup for later. It starts any number of machines, at any time, on any host:
From the TypeScript SDK:
fork copies a running or stopped machine. The server refuses to fork a paused machine, one with no host, or one on an older host, with 409 fork_unavailable, and creates nothing. Resume a paused machine first (it cannot be stopped while paused); otherwise save a snapshot and create from it.A fork is made only on the source’s host. When that host is under maintenance or full, the answer is the same code but retryable, with reason source_host_unavailable (maintenance) or source_host_full (no room), and nothing is created. Stop and start the machine to move it to another host, then fork it.With an older server that has no native fork, with a source host that is under maintenance or full, or with --keep-snapshot, the CLI saves a snapshot and creates the copies from it. It then deletes the snapshot, unless you passed --keep-snapshot.
fork keeps the source’s size, environment variables, and Secret selection. It also keeps the source’s auto-pause, max runtime, labels, and delete time (the same moment, so a source deleted in 2h gives copies deleted in 2h) unless you pass --auto-suspend, --max-run-minutes, --meta, or --delete-after. Your plan’s limits apply to these as they do on create: a kept value your plan does not allow is refused, and the error names the flag to pass. A machine created from a snapshot gets the plan’s default size unless you pass one. It also gets only the variables and Secrets in its own create request.
POST /v1/machines/{id}/fork answers the create operation. Its machineId is the new machine, and the new machine’s instabox-fork-of label names the source.

Snapshots

Save, fork, restore in place, and what a snapshot holds.

Errors

fork_unavailable and every other error code.