Skip to content

Sandboxes on exe.dev

A VM with its own CPU and memory, billed by the second while it runs.

A sandbox is an exe.dev VM with its own reserved vCPU and memory. An ordinary VM shares your plan's capacity with your other VMs; a sandbox doesn't take from it or add to it, and is metered by the second instead, from when you create it until you delete it, except while it's paused. That suits work you start, finish, and throw away: a CI job, an agent's task, code an LLM wrote, a preview of a branch.

It's still a whole VM, not a container: its own kernel, sudo, Docker, Go, Python and uv, an HTTPS address behind your exe.dev login, and the integrations attached to it. In our tests new --sandbox returned in about a second and the VM took commands right away. This page creates one, runs something in it, pauses and resumes it, deletes it, then does the same in bulk, and ends with what it costs next to a pool.

What you get#

  • A sandbox VM created with one command, ready for SSH in about a second
  • Work run in it from your computer, a script, or an agent
  • A paused sandbox that keeps its memory and processes and isn't billed for CPU or memory
  • Scripted creation for CI and agent jobs, each deleted when it ends
  • A sweep that finds and deletes sandboxes left running
What's running, and where
Private ssh my-sandbox.exe.xyz a shell in the sandbox, for the SSH keys on your account
Private https://my-sandbox.exe.xyz/ port 8000 of the sandbox, behind your exe.dev login, for previews
my-sandbox.exe.xyz exe.dev VM
Standalone VM exeuntu (Ubuntu 24.04), 2 vCPU / 4 GiB by default, reserved for this VM alone its own disk, kept while paused
Meter $0.105 per 2 vCPU / 4 GiB unit-hour, by the second, while it runs
Egress policy all by default; integrations to cut it off from the internet

Create a sandbox#

On your computer:

ssh exe.dev new --sandbox --name=my-sandbox

--sandbox is an alias for --standalone; the two are the same flag. Pick any free name (VM names are global, so my-sandbox may be taken), or leave --name off and exe.dev makes one up. The other new flags work as usual:

ssh exe.dev new --sandbox --name=my-sandbox --cpu=4 --memory=8GB --tag=sandbox --egress=integrations
  • Size. The default is 2 vCPU and 4 GiB. A sandbox can have up to 2 GiB of memory per vCPU, up to your plan's vCPUs on Personal and 32 vCPU on Work. ssh exe.dev resize my-sandbox --cpu=N --memory=M changes it later, and billing follows the new size.
  • Tags let you find and clean up sandboxes later.
  • --egress=integrations cuts the sandbox off from the internet except for the integrations attached to it. Use it for any sandbox an agent or untrusted code works in.
  • --no-email skips the email exe.dev sends about a new VM, which you want when a script makes hundreds.

Check that it's a sandbox:

ssh exe.dev ls --group=type

my-sandbox is listed under "Standalone VMs".

Note

Personal accounts can create sandboxes. On a Work team an admin turns them on first, with ssh exe.dev team settings standalone all-users (or admins-only) or at exe.dev/team. Until then new --sandbox is refused.

Run work in it#

A sandbox answers SSH for the keys on your account. On your computer:

ssh my-sandbox.exe.xyz 'nproc && free -m && python3 -c "print(6 * 7)"'

It prints 2, the memory table, and 42. For an interactive shell, ssh my-sandbox.exe.xyz. Everything else works as on any VM: scp files in and out, run Docker, start a server on port 8000 and open https://my-sandbox.exe.xyz/ (private to you until you share it), or point an agent at it. Claude Code, Codex, and Shelley are preinstalled.

An existing VM can become a sandbox too. ssh exe.dev cp my-vm my-sandbox-2 --sandbox copies it into a new sandbox, and ssh exe.dev pool detach --vm=my-vm turns a pool VM into one. A sandbox can't move into a pool.

Pause and resume#

When a sandbox has nothing to do but you'll want it again, pause it. On your computer:

ssh exe.dev pause my-sandbox

pause snapshots the VM's memory to its disk and frees its CPU and memory. It took about 2 seconds in our tests. ssh exe.dev ls my-sandbox now says paused. Commands sent to it through exe.dev fail with VM "my-sandbox" is not running, so resume it before you connect:

ssh exe.dev resume my-sandbox

About 3 seconds later the VM is back where it was, not rebooted: processes that were running are still running, and files in /tmp are still there. To see it, start something before you pause and look for it after:

ssh my-sandbox.exe.xyz 'nohup sleep 100000 >/dev/null 2>&1 &'
ssh exe.dev pause my-sandbox
ssh exe.dev resume my-sandbox
ssh my-sandbox.exe.xyz 'pgrep -a sleep'

It prints the same sleep 100000 process.

While it's paused, a sandbox isn't billed for its vCPU and memory. It keeps its disk, which counts toward your plan's disk allowance, and it still counts toward your VM limit (50 on Personal).

restart is not a pause: it reboots the VM, so processes are gone and files that hadn't reached the disk can be lost.

Delete it#

ssh exe.dev rm my-sandbox

The VM, its disk, and its capacity are gone, and so is the meter. rm takes several names at once: ssh exe.dev rm sbx-1 sbx-2 sbx-3.

Warning

A sandbox you forget about keeps running, and keeps costing $0.105 an hour for every 2 vCPU, until you pause or delete it. An 8 vCPU sandbox left up for a week is about $70. Pause what you'll come back to; delete the rest. Clean up shows how to find them.

Many sandboxes: CI and agent jobs#

Most sandboxes live for one job: seconds for a test run, minutes or hours for an agent's task. Create one per job, let exe.dev pick the name, and delete it however the job ends. This script runs a command in a fresh sandbox and passes its exit code through:

#!/usr/bin/env bash
# run-in-sandbox.sh 'cd /tmp && echo hello'
set -euo pipefail
vm=$(ssh exe.dev new --sandbox --tag=ci --no-email --json | jq -r .vm_name)
trap 'ssh exe.dev rm "$vm" >/dev/null' EXIT
ssh -o StrictHostKeyChecking=accept-new "$vm.exe.xyz" "$1"

--json makes new print the VM's details, vm_name among them, and the trap deletes the sandbox when the script exits, whether the command passed, failed, or was interrupted. Let exe.dev choose names: a name like ci-1234 is global and may belong to someone else.

To run several at once, start them in the background and wait. Three sandboxes created in parallel were all ready in under 2 seconds in our tests:

for i in 1 2 3 4 5; do ./run-in-sandbox.sh "echo job $i on \$(hostname)" & done; wait

Start each job from a prepared base#

Installing the same packages for every job is slow. Prepare a base once, pause it, and copy it for each job. Copying a paused sandbox took under half a second:

ssh exe.dev new --sandbox --name=my-sandbox-base --tag=ci
ssh my-sandbox-base.exe.xyz 'sudo apt-get update -q && sudo apt-get install -yq build-essential && sync'
ssh exe.dev pause my-sandbox-base

vm=$(ssh exe.dev cp my-sandbox-base --sandbox --json | jq -r .name)
  • Keep --sandbox on cp. Without it the copy goes into your pool, even when the source is a sandbox.
  • Run sync before you pause the base. A copy gets the base's disk, not its memory, and in our tests a file written just before the pause was empty in the copy until we added sync.
  • cp --json names the new VM in name, where new --json uses vm_name. The copy keeps the base's tags.
  • The paused base costs nothing for CPU and memory while it waits.

From code, without SSH keys#

The same commands work over the HTTPS API, which suits CI runners and agent platforms that shouldn't hold an SSH key. Make a token that can only touch VMs tagged ci. On your computer:

ssh exe.dev ssh-key generate-api-key --label=ci --tag=ci --exp=90d --cmds=new,ls,rm,ssh,cp,pause,resume

Every VM the token creates gets the ci tag, and it can see and touch no other VM. Then, wherever the job runs:

vm=$(curl -fsS -X POST https://exe.dev/exec -H "Authorization: Bearer $EXE_TOKEN" \
  -d 'new --sandbox --no-email' | jq -r .vm_name)
curl -sS -X POST https://exe.dev/exec -H "Authorization: Bearer $EXE_TOKEN" -d "ssh $vm uname -a"
curl -fsS -X POST https://exe.dev/exec -H "Authorization: Bearer $EXE_TOKEN" -d "rm $vm"

The API always answers in JSON. A command's exit code comes back in the X-Exe-Exit trailer; see Run commands on VM. The SDKs wrap all of this: exe.new(standalone=True) in Python and exe.new({ sandbox: true }) in TypeScript, with pause, resume, and copy as methods. An agent can drive sandboxes itself through the exe.dev MCP server.

Clean up what's left running#

Scripts crash and agents forget. List the sandboxes that are running now, with when they were made and their tags:

ssh exe.dev ls --json | jq -r '.vms[] | select(.type == "standalone" and .status == "running")
  | "\(.vm_name)\t\(.created_at)\t\(.tags // [] | join(","))"'

Pause the ones you'll want again and delete the rest. This deletes running sandboxes tagged ci that are more than an hour old, leaving paused ones, like a base, alone:

ssh exe.dev ls --json | jq -r '.vms[] | select(.type == "standalone" and .status == "running"
    and (.tags // [] | index("ci")) and (.created_at | fromdateiso8601) < now - 3600) | .vm_name' \
  | xargs -r ssh exe.dev rm

Run it from cron, or before each batch of jobs. With a --tag=ci token, ls already lists only ci VMs, so the sweep can't touch anything else.

What it costs#

exe.dev sells capacity two ways.

  • Pools are capacity you subscribe to, shared by your VMs. Personal is $15, $35, $75, or $155 a month for 2, 4, 8, or 16 vCPU (with 2 GiB of memory per vCPU), for up to 50 VMs. Work is $75 a month for the team, including 2 vCPU and 4 GiB across its pools; more pool capacity is $0.105 per unit-hour for as long as the pool has it. A VM in a pool costs nothing extra, running or idle, but it shares the pool's CPU with your other VMs.
  • Sandboxes are metered on their own: $0.105 per unit-hour, where a unit is 2 vCPU and 4 GiB, by the second, with no minimum. On Personal that's on top of your subscription. On Work, sandboxes and pools share the included 2 vCPU and 4 GiB, and the rest is metered at the same rate. Paused or stopped, a sandbox isn't billed for its CPU and memory.
Sandbox size Units Per hour If it runs all month
2 vCPU / 4 GiB 1 $0.105 $76.70
4 vCPU / 8 GiB 2 $0.21 $153.40
8 vCPU / 16 GiB 4 $0.42 $306.80
16 vCPU / 32 GiB 8 $0.84 $613.60

A month is 730.5 hours, as on exe.dev/pricing. Some worked examples:

  • CI. 500 test jobs a day, 15 seconds each, on 2 vCPU sandboxes: 500 ร— 15 s โ‰ˆ 2.08 unit-hours a day, about $0.22 a day or $6.56 over 30 days, and the jobs never slow down your other VMs.
  • Agent workers. 20 agent tasks a day, 30 minutes each, on 4 vCPU (2 units): 20 ร— 0.5 h ร— 2 = 20 unit-hours a day, $2.10 a day or $63 over 30 days.
  • A worker you pause. One 2 vCPU sandbox that works 2 hours a day and is paused the rest: 2 h ร— 30 = 60 unit-hours, $6.30 a month. Left running, it would be $76.70.
  • A box that stays up. A 2 vCPU sandbox running all month is $76.70. The same capacity on Personal is $15 and holds up to 50 VMs. A 2 vCPU sandbox costs more than $15 after about 143 hours in a month, roughly 4ยพ hours a day.
  • The one you forgot. An 8 vCPU sandbox (4 units) left running for a week: 4 ร— 168 h ร— $0.105 โ‰ˆ $70.56. Paused for that week, its CPU and memory cost nothing.

Sandbox or pool?#

Use a sandbox when the work is short or bursty and you'll throw the VM away: CI jobs, agent tasks, untrusted code, load tests, previews. You pay only while it runs, it can't slow down your other VMs, and on Work it doesn't need room in a pool.

Use a pool VM for what stays up: a dev box, an app, a bot, a database, an agent you talk to every day. Sharing a pool you already pay for is far cheaper than metering the same VM around the clock. Make it with plain ssh exe.dev new.

Between the two, a sandbox you pause when it's idle keeps its state for when you come back, and costs only its disk in between.

Troubleshooting#

  • new --sandbox is refused on a Work team: sandboxes are off until an admin runs ssh exe.dev team settings standalone all-users (or admins-only). The legacy Individual and Team plans don't include them.
  • VM "โ€ฆ" is not running: the sandbox is paused. ssh exe.dev resume <name>, then try again.
  • A copy is missing files the base had: they hadn't reached the base's disk when it was paused. Resume the base, run sync, pause it, copy again.
  • A copy isn't a sandbox: cp without --sandbox puts the copy in your pool. Check with ssh exe.dev ls --group=type.
  • --standalone cannot be combined: drop --pool or --no-pool.
  • Can't reach GitHub or a package registry: the sandbox was created with --egress=integrations. Use the GitHub integration, or ssh exe.dev egress <name> all if the job needs the internet.
  • Manage your billing: ssh exe.dev billing usage shows your usage against your plan (ssh exe.dev team usage on Work, or exe.dev/team/usage). To bring it down, find running sandboxes as in Clean up, then pause the ones you'll come back to and delete the rest. See Billing for plans and invoices.

Frequently asked questions#

Is --sandbox the same as --standalone?

Yes. --sandbox is an alias for --standalone on both new and cp, and the docs call these VMs standalone VMs. Neither can be combined with --pool or --no-pool.

How much does a sandbox cost?

$0.105 per unit-hour, where a unit is 2 vCPU and 4 GiB of memory, measured by the second with no minimum. A 2 vCPU sandbox that lives 15 seconds costs about $0.0004; one that runs all month costs about $76.70. On Personal it's on top of your subscription; on Work it shares the included 2 vCPU / 4 GiB with your pools. See What it costs.

Am I billed while a sandbox is paused?

Not for its vCPU and memory: metering stops when it's paused or stopped and starts again when you resume it. Its disk stays, so disk beyond your plan's allowance is still billed as usage, and it still counts toward your VM limit. rm stops everything.

What survives a pause?

Everything. pause snapshots the VM's memory to disk, so running processes, open files, and the disk are all there after resume, which in our tests took about 3 seconds and didn't reboot the VM. restart is different: it reboots, and processes are gone.

When should I use a pool VM instead?

For anything that stays up. A Personal plan's 2 vCPU / 4 GiB costs $15 a month and is shared by up to 50 VMs; the same capacity as a sandbox running all month is $76.70. A sandbox wins for short or bursty jobs you want to run without taking CPU from your other VMs: below about 143 unit-hours a month, it costs less than $15.

Can my Work team use sandboxes?

Yes, once an admin allows it: ssh exe.dev team settings standalone all-users (or admins-only), or at exe.dev/team. It's off until then. Personal accounts can create them right away; the legacy Individual and Team plans can't.

Can a sandbox reach the internet?

Yes, by default. new --sandbox --egress=integrations limits it to exe.dev metadata and the integrations attached to it, which is what you want for code you don't trust. See egress policy.

Updated Nov 2, 2026 · tested end to end Nov 2, 2026 · Markdown · manifest.json · Something wrong? Tell us