DaytonaDocs
Sandbox Lifecycle

VM Snapshots

Capture a sandbox's disk or full memory+disk state, and create new sandboxes from it.

A VM snapshot is a named, durable capture of a sandbox's state that you can restore into new sandboxes later — minutes or months after the source sandbox is gone. Where fork duplicates a sandbox right now, a snapshot is a checkpoint you keep: capture once, restore as many times as you like.

Snapshots come in two kinds. A disk snapshot captures the filesystem only, and sandboxes restored from it boot normally. A full snapshot captures memory and disk, and a sandbox restored from it resumes the captured processes — the same freeze-frame semantics as pause/resume, but reusable and named.

Note: VM snapshots are distinct from the image-alias snapshots used as sandbox base images. See Concepts → Snapshots for the difference.

Creating a snapshot

Capture a running sandbox with create_snapshot / createSnapshot, or POST /vms/:id/snapshots. The call returns immediately with a snapshot id; capture happens asynchronously and the snapshot moves pending → ready.

Python
result = sandbox.create_snapshot("after-setup", kind="disk")
print(result["snapshot_id"], result["job_id"])
 
# Or capture memory + disk so restores resume the running processes:
result = sandbox.create_snapshot("mid-training", kind="full")
TypeScript
const result = await sandbox.createSnapshot('after-setup', 'disk')
console.log(result.snapshotId, result.jobId)
 
// Or capture memory + disk so restores resume the running processes:
const full = await sandbox.createSnapshot('mid-training', 'full')
cURL
curl -X POST https://api.rl.trydaytona.com/vms/$SANDBOX_ID/snapshots \
  -H "Authorization: Bearer $RLP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "after-setup", "kind": "disk"}'

Snapshot names must be unique within your project; reusing a name returns 409 Conflict. The sandbox must be running — capturing a stopped or paused sandbox is not supported.

Tracking and managing snapshots

List your snapshots, fetch one (optionally blocking until it's ready), and delete ones you no longer need:

cURL
# List all snapshots in the project
curl https://api.rl.trydaytona.com/snapshots \
  -H "Authorization: Bearer $RLP_API_KEY"
 
# Get one — ?wait=ready long-polls until capture completes
curl "https://api.rl.trydaytona.com/snapshots/$SNAPSHOT_ID?wait=ready" \
  -H "Authorization: Bearer $RLP_API_KEY"
 
# Delete
curl -X DELETE https://api.rl.trydaytona.com/snapshots/$SNAPSHOT_ID \
  -H "Authorization: Bearer $RLP_API_KEY"

Restoring

Restore by creating a new sandbox whose image references the snapshot by name. A disk restore boots the filesystem normally (fresh processes); a full restore resumes the captured processes and memory.

cURL
curl -X POST https://api.rl.trydaytona.com/vms \
  -H "Authorization: Bearer $RLP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image": { "type": "snapshot", "name": "after-setup" }
  }'

Two constraints apply at restore time:

  • The snapshot must be ready; restoring from a pending snapshot returns 409 Conflict. Use ?wait=ready (above) to block until capture finishes.
  • Full snapshots are region-pinned: because they embed live machine state, a sandbox restored from a full snapshot is created in the snapshot's home region. Disk snapshots have no such restriction.

What a snapshot does not capture

A snapshot covers the sandbox's own state; resources that live outside the sandbox are excluded:

ExcludedWhy
Docker data deviceIt's ephemeral scratch (docker_data_mib), not part of the sandbox filesystem.
Attached volumesVolumes are independent, shareable resources with their own lifecycle. Re-attach them to the restored sandbox at create time.
Network identityA restored sandbox always gets a fresh IP and fresh port mappings.

A checkpoint → restore workflow

A common agent pattern: set up an environment once, snapshot it, and restore a clean copy per task.

Python
from rlp import CreateSandboxFromImageParams, Daytona
 
daytona = Daytona()
 
# One-time: build and capture the environment.
base = daytona.create(CreateSandboxFromImageParams(image="python:3.12-slim"))
base.process.exec("pip install requests beautifulsoup4")
base.create_snapshot("scraper-env", kind="disk")
# ...poll GET /snapshots/:id?wait=ready, then the base sandbox can be deleted.

Every later task then starts from scraper-env in seconds instead of re-installing, by creating its sandbox from the snapshot as shown in the cURL restore example above.

See also

  • Fork — immediate duplication of a live sandbox, no named artifact.
  • Pause & Resume — park one sandbox with its memory, without creating anything restorable.
  • Image sources — all the ways to specify what a new sandbox boots from.

On this page