VMs, pools and standalone VMs
A pool is CPU and memory reserved for you in one region. The VMs you put in it share that capacity: one VM can use all of it, or many can split it. “A pool is billed for as long as it exists, empty or full.”
Sources: https://exe.dev/docs/pools, https://exe.dev/docs/standalone-vms, https://exe.dev/docs/customization, https://exe.dev/docs/migrating-to-pools.
Pools by plan
| Plan | Pools | Capacity | Source |
|---|---|---|---|
| Personal | One pool, your account’s capacity | 2 to 16 vCPU, shared by all your VMs | https://exe.dev/docs/pools |
| Work | As many as needed, billed by the hour | Any even number of vCPU from 2 to 512, 2 GiB memory per vCPU | https://exe.dev/docs/pools |
| Enterprise | Custom capacity on dedicated hardware | Contract | https://exe.dev/docs/enterprise |
Things to remember:
- Capacity units. Capacity comes in units of 2 vCPU and 4 GiB.
- VM limits. A pool holds up to 1,000 VMs, and “There is no team-wide VM limit.”
- What a pool reserves. Pools reserve CPU and memory, not disk.
- What changes the bill. Adding VMs doesn’t change the cost; resizing does.
- Starting size. A new Work team starts with a 2 vCPU / 4 GiB pool.
Kinds of pool
- Shared team pool. An admin creates it with
pool new, and any member can create VMs in it. - Member pool. When default placement is
member-pool, each member gets a pool of their own the first time they runnewwithout--pool. - Standalone VM. “A pool of one, sized to the VM and metered by the second while the VM runs.”
Sizes and approval
- Pools up to 32 vCPU take effect immediately.
- Pools above 32 vCPU, up to 512, need approval from exe.dev support. A pending pool accepts no VMs and is not billed.
- Shrinking takes effect immediately, but a pool cannot shrink below its largest VM.
- Teams with dedicated hosts skip approval. Pools there “take effect immediately at any size a host can take” (https://exe.dev/docs/enterprise-single-tenant).
Pool commands (admins only)
pool new build --cpus=8 --region=lax # create
new --pool=build # put a new VM in it
cp my-vm my-vm-copy --pool=build # copy a VM into it
pool resize build --cpus=16 # resize (does not resize VMs)
pool resize build --max-vms=200
pool adopt --vm=<vm> --pool=<pool> # move a pre-pool team VM in
pool detach --vm=<vm> # becomes standalone; cannot be undone
pool list # region, size, VM count, usage
Default placement
team settings vm-placement pool build # one shared pool
team settings vm-placement member-pool --cpus=4 # a pool per member
team settings vm-placement poolless # outside any pool (legacy)
team settings vm-placement default # clear the setting
new --pool=<name> always overrides the default.
Standalone VMs (sandboxes)
A standalone VM has capacity of its own, outside any pool. It is “metered by the second while it runs” at $0.105 per 2 vCPU / 4 GiB unit-hour, with no minimum (https://exe.dev/docs/standalone-vms).
| Size | Monthly if run all month (730.5 h) |
|---|---|
| 1 vCPU / 2 GiB | $38.35 |
| 2 vCPU / 4 GiB | $76.70 |
| 4 vCPU / 8 GiB | $153.40 |
| 8 vCPU / 16 GiB | $306.80 |
| 16 vCPU / 32 GiB | $613.60 |
Source: https://exe.dev/docs/standalone-vms.
Things to remember:
- How to create one. Use
new --standalone, or--sandbox. - Who can create them. On Work and Enterprise, admins decide with
team settings standalone admins-only|all-users|off. - Memory. Up to 2 GiB per vCPU.
- Stopped VMs. These are not billed for CPU or memory.
- No moving back. A standalone VM can’t move into a pool, and
pool detachmakes a pooled VM standalone permanently. - Limits. Personal allows 50 standalone VMs at up to 16 vCPU / 32 GiB. Work allows 100 at up to 32 vCPU / 64 GiB (https://exe.dev/pricing).
Standalone VMs fit spiky, short-lived work: agent-written code, CI jobs and previews. Pools fit long-lived VMs that can share capacity.
Images and customization
- Default image.
exeuntuis about 4 GB. Its Dockerfile is open source at https://github.com/boldsoftware/exeuntu. If you want something smaller, build your own image (https://exe.dev/docs/faq/disk-usage). - Custom image. Use
ssh exe.dev new --image=myorg/my-custom-image:latest. - Image labels.
LABEL exe.dev/install-shelley=trueinstalls a recent Shelley at creation.exe.dev/login-user=...sets the SSH user. - Setup scripts. exeuntu runs
/exe.dev/setuponce, at first boot. You can pass a script withnew --setup-script, or set a default withcat script | ssh exe.dev defaults write dev.exe new.setup-script. “Setup scripts have a maximum size. Use indirection.” - Private registries. Booting from a private image takes
--registry-auth=USERNAME:TOKEN. Inside a running VM, use a container registry integration so there’s nodocker loginand no credential on the VM (https://exe.dev/docs/private-image). - Docker. “Sure, why not; it’s just a VM.” Try
docker run --rm alpine:latest echo hello(https://exe.dev/docs/faq/docker).
Customization pattern
cat setup.sh | ssh exe.dev new --setup-script /dev/stdin
ssh exe.dev new --name my-vm --image=ghcr.io/OWNER/IMAGE:TAG --registry-auth=USERNAME:TOKEN
Moving files
- Use
scp file.txt my-vm.exe.xyz:~/. - If
scpisn’t available, use atarpipe over SSH (https://exe.dev/docs/faq/copy-files).
Migrating onto exe.dev
“exe.dev VMs are just Linux VMs. The secret ninja trick is to let your LLM of choice do the migration for you.” Point your agent at https://exe.dev/llms.txt. Have the web app listen on localhost:8000, the default share port for exeuntu, and it appears at https://vm-name.exe.xyz/ (https://exe.dev/docs/migrating-to-exe).
Leaving exe.dev is just as plain: “If you need to migrate off to another provider, rsync will get you pretty far” (https://exe.dev/docs/lockin).