# VM pools


A pool is an amount of vCPU and memory reserved for you in one region. The
VMs you place in a pool share that capacity. One VM can use all of it, or many
VMs can split it.

A pool is billed for as long as it exists, empty or full. Adding VMs doesn't
change the cost; resizing does. Pools reserve CPU and memory, not disk.

## Pools and plans

- **Personal** has one pool: your account's capacity, from 2 to 16 vCPU,
  shared by all your VMs. You can't create more pools.
- **Work** can have as many pools as it needs, billed by the hour.
- **Enterprise** pools have custom capacity, dedicated hardware, and contract
  pricing.

See [Personal](/docs/billing/personal), [Work](/docs/billing/work), and
[Enterprise](/docs/billing/enterprise) for plan prices, and
[exe.dev/pricing](https://exe.dev/pricing) for the full comparison.

## Kinds of pools

**Shared team pool.** A team admin creates it with `pool new`. Any member of
the team can create VMs in it.

**Member pool.** When [default placement](#default-placement) is
`member-pool`, each member gets a pool of their own the first time they run
`new` without `--pool`. Everyone on the team sees it
in `pool list`, but only that member creates VMs in it.

**Standalone VM.** A standalone VM (sandbox) is a pool of one, sized to the
VM and billed by the hour while the VM runs. See
[Standalone VMs](/docs/standalone-vms).

## Capacity, disk, and bandwidth

Pool capacity comes in units of 2 vCPU / 4 GB of memory. On Work, a pool can
be any even number of vCPU from 4 to 512, with 2 GB of memory per vCPU.

A Work pool holds up to 25 VMs per vCPU, up to 1,000 VMs. A 4 vCPU pool holds
100 VMs, and a 32 vCPU pool holds 800. There is no team-wide VM limit.

Work's $150/month minimum spend covers 4 vCPU / 8 GB of capacity, counted
across all of the team's pools and standalone VMs together. Capacity beyond that is metered
at $0.105 per 2 vCPU per hour. For example, a team with one 8 vCPU pool pays
the minimum spend plus $0.21 per hour for the 4 vCPU above the included
capacity. A pool that is pending approval is not billed.

On Work, each pool also carries included disk and outbound bandwidth, based on
its configured capacity:

- **Disk:** 100 GB per 2 vCPU, averaged over the billing period.
- **Bandwidth:** 50 GB per vCPU per billing period, prorated by how long the
  capacity existed.

The allowance belongs to the pool, including the 4 included vCPU. It covers
that pool's VMs and doesn't move between pools. On Personal it belongs to your
account.

Additional disk is charged per GiB-month. Additional bandwidth is metered and
priced at the rate on [exe.dev/pricing](https://exe.dev/pricing). See
[Usage](/docs/billing/usage) for how both are measured.

## Regions

A pool lives in one region, and its VMs run there. Pick any region
`pool new` lists with `--region=<code>`, including one outside your account's
region. Pools do not move between regions.

## Sizes and approval

Pool sizes up to 32 vCPU take effect immediately. Larger sizes, up to
512 vCPU, need approval from exe.dev support:

- `pool new` above 32 vCPU creates a pending pool that accepts no VMs until
  [support](mailto:support@exe.dev) activates it.
- `pool resize` that grows an active pool above 32 vCPU records a request. The
  pool keeps its current size until support approves it.
- Shrinking a pool takes effect immediately.

## Default placement

You don't have to name a pool when you create a VM. If you leave out
`--pool`, the VM goes where the team's default placement says. On Work and
Enterprise, a team admin sets it, and switching to Work sets it to your first
pool.

```
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
```

- **pool:** every member's new VMs go to that pool.
- **member-pool:** each member gets a pool of that size the first time they
  run `new`. `--max-vms` sets a lower VM limit.
- **poolless:** new VMs stay outside pools, so you can
  [migrate](/docs/migrating-to-pools) on your own schedule instead of having
  every new VM land in a pool right away. Available only while the team still
  has VMs outside pools.
- **default:** `new` without `--pool` fails until an admin sets placement
  again, unless the team still has VMs outside pools.

`team settings vm-placement` shows the current setting. Admins can also change
it at [exe.dev/team](https://exe.dev/team). `new --pool=<name>` always
overrides it.

## Using pools

Only team admins can create, resize, adopt into, or delete pools.

### Create a pool

```
pool new build --cpus=8 --region=lax
```

`--max-vms` sets a VM limit below the pool's size-based maximum.

### Put VMs in a pool

```
new --pool=build
cp my-vm my-vm-copy --pool=build
```

A VM in a pool can be sized up to the pool's capacity. Without `--pool`,
`new` follows the team's [default placement](#default-placement).

### Resize a pool

```
pool resize build --cpus=16
pool resize build --max-vms=200
```

Resizing a pool does not resize its VMs. To give a VM more of the new
capacity, resize the VM with `resize <vm>`.

A pool cannot shrink below the size of its largest VM. Resize that VM first.

### Move VMs in and out

`pool adopt --vm=<vm> --pool=<pool>` moves a team VM that is outside any pool
into a pool. This can take several minutes.

`pool detach --vm=<vm>` turns a VM in a pool into a standalone VM with its own
capacity, billed by the hour. This cannot be undone. The pool keeps its
capacity and billing. Detaching follows the team's standalone setting, which
is off until an admin sets it (see [Standalone VMs](/docs/standalone-vms)).

While the team still has VMs outside pools, an admin can run
`pool detach --vm=<vm> --poolless` instead. The VM leaves its pool and keeps
running outside any pool. The pool keeps its capacity and billing. Once every
VM is in a pool, `--poolless` is no longer available.

### VMs outside a pool

Team VMs from before pools stay outside any pool until an admin moves them in
with `pool adopt`. See [Migrating to pools](/docs/migrating-to-pools).

### Check usage

- `pool list` shows each pool's region, size, VM count, and recent CPU use.
- `pool list build --usage --range=7d` shows CPU history for one pool.
- `team usage` shows pool capacity, included capacity, disk, and bandwidth for
  the billing period. It is limited to admins and billing owners.
- [exe.dev/team/pools](https://exe.dev/team/pools) and
  [exe.dev/team/usage](https://exe.dev/team/usage) show the same in the
  browser.

### Delete a pool

`pool delete build` refuses while the pool has VMs. Billing for the pool stops
when it is deleted.

While the team still has VMs outside pools, `pool delete build --force` deletes
it anyway, and its VMs keep running outside any pool. Once every VM is in a
pool, `--force` is no longer available. Delete the pool's VMs first.

A member pool cannot be force-deleted. Delete its VMs first, and switch
placement away from `member-pool` before deleting it.

## Next steps

- [`pool`](/docs/cli-pool) command reference
- [Migrating to pools](/docs/migrating-to-pools)
- [Standalone VMs (sandboxes)](/docs/standalone-vms)
- [`new`](/docs/cli-new) and [`cp`](/docs/cli-cp) for `--pool` and
  `--standalone`
- [`team`](/docs/cli-team) for the placement and standalone settings
- [Team VMs](/docs/teams/vms)
- [Billing overview](/docs/billing/overview) and [Usage](/docs/billing/usage)
