---
title: Volumes and snapshots
description: Carry work past the end of a lease with a persistent disk, or boot a new lease from a captured moment.
type: how-to
product: sandboxes
summary: What survives a lease, and what a new lease can start from
updated: 2026-09-28
order: 2
---

A lease's disk lives exactly as long as the lease. Two objects carry work past
that: a Volume, which is a disk of its own, and a Snapshot, which is a lease's
disk and image captured at one moment.

## Volumes

A Volume is a persistent disk scoped to one environment, encrypted at rest,
and created with the size you want:

```bash
sylphx sandboxes volumes create \
  --parent orgs/acme/projects/shop/envs/production \
  --spec.size-gib 1
```

```bash
curl -X POST "https://api.sylphx.com/v1/orgs/acme/projects/shop/envs/production/volumes" \
  -H "Authorization: Bearer $SYLPHX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"spec":{"size_gib":1}}'
```

```ts
const response = await sylphx.sandboxes.volumes.create({
  parent: 'orgs/acme/projects/shop/envs/production',
  volume: { spec: { sizeGib: 1 } },
})
```

It is attached by name when the lease is created:

<PropertyTable
	properties={[
		{
			name: 'volume',
			type: 'string',
			description: 'The volume to attach. Required.',
		},
		{
			name: 'mount_path',
			type: 'string',
			description: 'The absolute guest path. Defaults to `/home/user/volumes/{volume id}`.',
		},
		{
			name: 'read_only',
			type: 'bool',
			description: 'Mount the volume read-only.',
		},
	]}
/>

The lease becomes the volume's one writer, fenced by that lease's generation,
so a mount is not a shared folder: a volume is attached to at most one lease
at a time, and a create that names an already-attached volume is refused
`RESOURCE_IN_USE`. That is the property to design around. Two machines
writing one disk is the failure this prevents.

The volume outlives the lease. When the lease ends the volume is detached and
the data stays, and the next lease that mounts it sees what the last one
wrote. Nothing about the lease destroys it: a Volume is destroyed only by
`delete`, and that call is refused `RESOURCE_IN_USE` while the volume is
attached. `update` grows `spec.size_gib` and edits its metadata.

<Callout tone="note" title="A volume is not a backup">
Encryption at rest protects the disk, not the data on it. A `delete` destroys
the volume and its contents, and nothing restores them. Anything you cannot
recreate belongs somewhere that is meant for copies.
</Callout>

## Snapshots

A Snapshot captures a running lease's disk and image at one moment:

```bash
sylphx sandboxes snapshots create \
  --parent orgs/acme/projects/shop/envs/production \
  --spec.source-lease lease
```

```bash
curl -X POST "https://api.sylphx.com/v1/orgs/acme/projects/shop/envs/production/snapshots" \
  -H "Authorization: Bearer $SYLPHX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"spec":{"source_lease":"lease"}}'
```

```ts
const response = await sylphx.sandboxes.snapshots.create({
  parent: 'orgs/acme/projects/shop/envs/production',
  snapshot: { spec: { sourceLease: 'lease' } },
})
```

A lease created with `source_snapshot` boots from it — its disk and its image
— instead of from `spec.image`, which is ignored in that case. That makes the
useful pattern a two-step one: set a machine up once, snapshot it at the
moment it is ready, and start every lease after that from the snapshot rather
than repeating the setup.

Process memory is not captured. A lease booted from a snapshot starts its
processes fresh, exactly as a resumed lease does, so a snapshot is a starting
point for work rather than a paused machine. Use `pause` for the latter — and
read [the lifecycle page](/docs/sandboxes/leases) when the difference between
paused, snapshotted and ended matters.

## Pools

A Pool keeps never-leased machines of one shape and image warm, so a lease
starts in seconds instead of waiting for a boot. `spec.pool` names one, and
unset means the platform's own pool for that shape and image.

The property worth knowing: a pool changes how fast a lease arrives, never
what you get. A lease served from a warm machine is the same shape, the same
image and the same isolation as one that took longer, so nothing you write
has to depend on the pool in order to be correct. [The pools
collection](/docs/api/pools) carries the spec, including the bounds on warm
machines, and the operations.

<RelatedDocs
	links={[
		{
			href: '/docs/api/volumes',
			label: 'The volumes collection',
			description: 'Every method, its scope and its examples.',
		},
		{
			href: '/docs/api/snapshots',
			label: 'The snapshots collection',
			description: 'Creating a snapshot and deleting one.',
		},
		{
			href: '/docs/api/pools',
			label: 'The pools collection',
			description: 'Warm machines, their counts and their operations.',
		},
		{
			href: '/docs/sandboxes/leases',
			label: 'Lease lifecycle',
			description: 'Pause, resume, and what a lease keeps when it ends.',
		},
	]}
/>
