Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/deeplethe/forkd/llms.txt

Use this file to discover all available pages before exploring further.

Snapshots are the warm parent images that every sandbox child forks from. A snapshot captures a fully-booted, dependency-warmed guest VM — its memory image (memory.bin) and saved vCPU + device state (vmstate) — so that children can start from it copy-on-write in milliseconds rather than cold-booting from scratch. Snapshots can be created from a kernel and rootfs pair (POST /v1/snapshots) or by branching from a running sandbox (POST /v1/sandboxes/:id/branch). Starting with v0.5, snapshots can be chained into diffs — each link records only the dirty pages added by one install step — and chains can be inspected, safety-checked before deletion, and compacted back to a flat image.

POST /v1/snapshots

Build a snapshot from a freshly booted parent VM and register it under a tag. The daemon boots a Firecracker VM with the supplied kernel and rootfs, waits boot_wait_secs for userspace to warm up inside the guest, then pauses the VM and saves the memory image and vmstate to disk. This call blocks for the full boot-and-warmup duration (typically 10–30 seconds depending on the rootfs). Use the resulting tag with POST /v1/sandboxes to fork children. Request body
tag
string
required
Unique name for this snapshot. Must match ^[A-Za-z0-9_][A-Za-z0-9._-]{0,63}$. Returns 400 Bad Request if the tag already exists.
kernel
string
required
Absolute path on the host to the uncompressed kernel image (e.g. vmlinux-6.1).
rootfs
string
required
Absolute path on the host to the ext4 rootfs image.
rw
boolean
default:"false"
Mount the rootfs read-write inside the guest during warmup. Useful when the warmup script writes files (e.g. pre-compiled .pyc caches). The on-disk image is modified directly; subsequent children inherit the writes.
tap
string
Name of the host TAP device to attach for guest networking (e.g. forkd-tap0). Omit for network-less snapshots.
boot_wait_secs
integer
default:"10"
How long to wait (in seconds) after the guest kernel boots before pausing. Increase this for rootfs images whose warmup scripts (imports, JIT compilation, model loading) take longer than the default.
Response — 201 Created Returns a SnapshotInfo object for the newly registered snapshot.
{
  "tag": "py",
  "dir": "/var/lib/forkd/snapshots/py",
  "created_at_unix": 1717000000
}
Errors
StatusCause
400 Bad RequestInvalid tag, missing kernel or rootfs, or snapshot tag already exists.
500 Internal Server ErrorFirecracker boot or snapshot failure — check the daemon logs.

GET /v1/snapshots

List every snapshot registered with the daemon. Returns an array of SnapshotInfo objects sorted by creation time. Response — 200 OK
[
  {
    "tag": "py",
    "dir": "/var/lib/forkd/snapshots/py",
    "created_at_unix": 1717000000
  },
  {
    "tag": "checkpoint-1",
    "dir": "/var/lib/forkd/snapshots/checkpoint-1",
    "created_at_unix": 1717000900,
    "branched_from": "sb-67a1b3-0000",
    "pause_ms": 1820,
    "status": "ready"
  }
]

DELETE /v1/snapshots/:tag

Remove a snapshot’s registry entry and delete its on-disk files. Returns 204 No Content on success. Path parameter
tag
string
required
The snapshot tag to delete.
Query parameters — v0.5 chain safety When the tag is the recorded parent_tag of one or more other snapshots, the daemon refuses with 409 Conflict unless the caller opts in via a query parameter.
cascade
boolean
default:"false"
Recursively delete the tag and every descendant snapshot in its subtree. Use this when you want to remove a whole diff chain at once.
force
boolean
default:"false"
Delete the tag even though doing so leaves child snapshots orphaned. Orphaned children record a parent_tag that no longer exists on disk; they will fail to restore. Use only if you accept that breakage.
cascade and force are mutually exclusive. Supplying both in the same request returns 400 Bad Request.
409 Conflict response body example When neither cascade nor force is set and the snapshot has dependents, the response body names every blocking child:
{
  "error": "snapshot `py-numpy` is the parent of 1 chained snapshot(s): [py-pandas]; rerun with `?cascade=true` to delete the whole subtree, or `?force=true` to orphan the children (they will fail to restore)"
}
Errors
StatusCause
400 Bad RequestBoth cascade=true and force=true were supplied.
404 Not FoundNo such tag in the registry and no on-disk files found.
409 ConflictThe tag is a parent of one or more chained snapshots; re-run with ?cascade=true or ?force=true.

GET /v1/snapshots/:tag/info

Added in v0.5. Use this before deleting or compacting a chained snapshot to understand its depth, ancestors, and dependents.
Return detailed chain and on-disk information for a single snapshot. The response extends the base SnapshotInfo shape with per-link sizes, chain depth, and the full ancestor + dependent lists. Path parameter
tag
string
required
The snapshot tag to inspect.
Response — 200 OK Returns a SnapshotInfoDetail object.
{
  "tag": "py-pandas",
  "dir": "/var/lib/forkd/snapshots/py-pandas",
  "created_at_unix": 1780556400,
  "memory_logical_bytes": 536870912,
  "memory_physical_bytes": 536875008,
  "vmstate_bytes": 21900,
  "parent_tag": "py-numpy",
  "parent_content_hash": "276c99e9...",
  "chain_depth": 2,
  "ancestors": ["py-base", "py-numpy"],
  "dependents": []
}
Errors
StatusCause
404 Not FoundTag not in the registry and no on-disk directory found.

POST /v1/snapshots/:tag/compact

Added in v0.5. Use this to collapse a deep diff chain into a single flat snapshot and eliminate the per-link SHA-256 verification cost at spawn time.
Walk the diff chain rooted at :tag, verify every per-link parent content hash, assemble the head’s full memory image, and persist the result as a new flat (parentless) snapshot under req.to. The new snapshot restores via the standard non-chain code path with no per-link overhead. The daemon stages the result to a sibling .compact-staging-<to>/ directory and rename(2)s it into place atomically, so a mid-compact crash never leaves a half-written destination snapshot behind. Path parameter
tag
string
required
The chain-head snapshot tag to compact. The daemon walks from this tag back to the chain root.
Request body
to
string
required
Tag for the new flat snapshot. Must not already exist and must match the standard tag pattern ^[A-Za-z0-9_][A-Za-z0-9._-]{0,63}$.
Response — 201 Created Returns a SnapshotInfo for the newly created flat snapshot.
{
  "tag": "py-pandas-flat",
  "dir": "/var/lib/forkd/snapshots/py-pandas-flat",
  "created_at_unix": 1780560000
}
Errors
StatusCause
400 Bad Requestto equals :tag (self-compact), or either tag contains unsafe characters.
409 ConflictA snapshot with the tag given in to already exists. DELETE it first.
500 Internal Server ErrorChain verification or assembly failure — check daemon logs.

Schemas

SnapshotInfo

The base shape returned by POST /v1/snapshots, GET /v1/snapshots, and POST /v1/sandboxes/:id/branch.
{
  "tag": "py",
  "dir": "/var/lib/forkd/snapshots/py",
  "created_at_unix": 1717000000,
  "branched_from": "sb-67a1b3-0000",
  "pause_ms": 1820,
  "status": "ready"
}
tag
string
required
The snapshot’s registered tag name.
dir
string
required
Absolute path to the snapshot directory on the host filesystem. Contains memory.bin and vmstate.
created_at_unix
integer
required
Unix timestamp (seconds) when the snapshot was registered.
branched_from
string
Present only for branch-produced snapshots. The source sandbox ID that was paused to create this snapshot (e.g. "sb-67a1b3-0000"). Omitted when the snapshot was built from kernel + rootfs via POST /v1/snapshots. Use this field to trace snapshot lineage and audit which sandbox state a snapshot captures.
pause_ms
integer
Present only for branch-produced snapshots. The measured source-VM pause window in milliseconds (from pause() to resume()). This is the daemon’s ground truth; the application-observed pause (TCP stalls, missed pings) may be longer due to OS retransmit timers. Omitted for snapshots built via POST /v1/snapshots.
status
string
Snapshot lifecycle state. Added in v0.4; omitted on older snapshots (treat absence as "ready").

SnapshotInfoDetail (v0.5)

Returned exclusively by GET /v1/snapshots/:tag/info. Extends SnapshotInfo with per-link sizes and full chain metadata.
tag
string
required
The queried tag.
dir
string
required
Absolute path to the snapshot directory.
created_at_unix
integer
Unix timestamp from the registry. Absent for on-disk-only snapshots that were never registered (e.g. discovered by scanning the snapshot directory).
memory_logical_bytes
integer
required
stat().st_size of memory.bin — the full logical size of the guest RAM image, regardless of sparse or reflink layout.
memory_physical_bytes
integer
required
st_blocks × 512 — allocated bytes on disk. On reflink or sparse filesystems this is smaller than memory_logical_bytes because unchanged pages share physical extents with the parent.
vmstate_bytes
integer
required
Size in bytes of the vmstate file (saved vCPU + device register state). Typically 20–30 KiB.
parent_tag
string
Direct parent in the v0.5 diff chain. Absent for base (flat) snapshots.
parent_content_hash
string
SHA-256 of the parent’s memory.bin (or diff.bin for an already-chained parent) recorded at chain-build time. Absent for base snapshots. The daemon verifies this hash during chain assembly at spawn time to detect corruption or accidental file replacement.
chain_depth
integer
required
Number of diff links between this snapshot and its chain root. 0 for a base (flat) snapshot, 1 for a single diff over a base, and so on.
ancestors
string[]
required
Tags walked from the chain root to this snapshot’s direct parent (root → parent order). Empty for base snapshots. ancestors[0] is always the chain root.
dependents
string[]
required
Tags whose parent_tag equals this tag — i.e. snapshots that would be orphaned by a plain DELETE without ?cascade or ?force. Empty when this snapshot is a chain leaf.

Build docs developers (and LLMs) love