Skip to content
Fuse
Esc
navigateopen⌘Jpreview
On this page

Snapshots

Capturing and restoring a running microVM's state

client.snapshots captures and restores the state of a running microVM. Take a snapshot before something risky, and restore if it goes wrong:

const snap = await client.snapshots.create(env.id, {
  comment: "before risky migration",
  mode: "manual",
});

// ... do the risky thing ...

await client.snapshots.restore(snap.id);
  • create’s vmId must be a running environment. body is optional, omit it for a plain snapshot with no metadata; mode is "manual" or "auto", and retention_seconds of 0 keeps it forever.
  • restore is in place only: it restores onto the snapshot’s original VM, which must still be running. There is no cross-host restore, clone, or standalone restore into a new VM, use fork on the environments service for that instead.

Live snapshots

live in the create body opts into capturing the guest’s memory and vCPU state alongside the disk. Omit it, or pass false, for a disk-only snapshot, which is the default everywhere and the fallback:

const snap = await client.snapshots.create(env.id, {
  comment: "warmed model loaded",
  live: true,
});
// snap.kind is "live" here, "disk" on every other snapshot

snapshot.kind is "live" or "disk" and is set by the host agent, not by the caller reading its own request back. restore takes no live counterpart: it reads the kind off the snapshot and either resumes the guest or cold-boots it.

The trade-offs are the same ones documented under Snapshots, and they are sharp enough to repeat:

  • snapshot.size_bytes on a live snapshot includes a full copy of the environment’s configured memory, on every create. Tenant byte quotas were calibrated for rootfs-only snapshots, so a create loop with live: true will hit the byte quota much sooner than the snapshot count implies.
  • the guest is paused for the duration of the capture.
  • a live snapshot cannot seed a new environment. fork and CreateRequest.seed_snapshot_id read only a snapshot’s rootfs, and a live snapshot’s rootfs is captured without quiescing the guest filesystem, so it mounts cleanly only alongside its memory image. Both reject one with 409 conflict. Take a disk snapshot when you want a copy rather than a rewind.
  • a live snapshot is pinned to the host that took it. The memory image depends on that host’s CPU model and Firecracker version.

live: true against a backend with no live-snapshot support throws a FuseApiError with code === "unimplemented" and status === 501, not a conflict. The message says to retry without live for a disk snapshot.

snapshot.kind is worth checking rather than assuming: a host running an agent too old to know about live snapshots answers live: true with a disk snapshot, and the record then says "disk". Recording the request rather than the result would file a cold-booting artifact as a resumable one.

Everything else

Method Purpose
list({ vmId, taskId, tenantId, state }) List snapshots, all filters optional.
get(snapshotId) Fetch one snapshot’s full detail, including state (creating|ready|restoring|deleting|error), kind (disk|live), and exports.
delete(snapshotId) Leaf-only delete; also removes the underlying provider artifact. No soft-delete.

These mirror the HTTP API one to one.

The QEMU/GPU exception

Environments running on the QEMU backend (whole-GPU passthrough) cannot be snapshotted or forked at all, create and restore against a GPU environment throw a FuseApiError with code === "conflict" rather than silently no-op-ing. See Providers.

Was this page helpful?