Snapshots are the foundation of the forkd fork-on-write model. A snapshot captures a paused, warmed parent VM — its vCPU state, memory image, and device config — so that child processes canDocumentation 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.
mmap the memory file with MAP_PRIVATE and start running immediately without a cold boot. This page documents every CLI verb that creates, inspects, modifies, or removes snapshots.
forkd quickstart
Zero-to-first-fork in one command. Designed for first-time setup on a fresh host. Run as sudo -E forkd quickstart.
What it does, step by step:
- Runs the doctor preflight (platform, hardware virt, KVM, Firecracker binary) and fails fast if any blocking check fails.
- Identifies which setup steps the host still needs: guest kernel download, tap device creation, per-child netns provisioning.
- Lists the required steps and prompts for confirmation (or accepts
--yesfor non-interactive use). - Executes the missing steps using embedded copies of the repo’s idempotent setup scripts (
install-guest-kernel.sh,host-tap.sh,netns-setup.sh). - Chooses a snapshot route: reuses an existing
quickstarttag → local Docker bake viafrom-image→ hub pull ofdeeplethe/python-numpy(when Docker is absent). - Calls
forkd fork --tag quickstart -n N --per-child-netnsand prints per-child timings. - Prints suggested next commands.
Number of children to fork for the demo.
Docker image the parent snapshot is baked from. Ignored when Docker is unavailable (hub pull route is used instead).
Answer yes to all setup prompts (kernel download, tap creation, netns provisioning) without interactive confirmation. Suitable for CI / non-interactive use.
forkd snapshot
Boot a fresh parent VM from a kernel and rootfs, warm it up, pause it, and write the snapshot to $XDG_DATA_HOME/forkd/snapshots/<tag>/. Alternatively, with --from-sandbox, branch a running child sandbox via the controller daemon — no local boot required.
Local boot path (default): boots a Firecracker VM, waits --boot-wait-secs for the guest to settle (imports, JIT warmup, model loading), pauses the vCPUs, writes vmstate and memory.bin, then kills the parent VM. The snapshot.json metadata file records volume specs for subsequent forkd fork calls.
Daemon branch path (--from-sandbox): calls POST /v1/sandboxes/<id>/branch on the controller. The source sandbox is paused only for the snapshot window (0.5–8 s for Full; ~200 ms for Diff; sub-50 ms for Live). After this call, --kernel, --rootfs, --tap, --boot-wait-secs, --mem-size-mib, and --volume are all ignored — the branch inherits those settings from the source’s snapshot.
Name of the snapshot tag. The snapshot is stored at
$XDG_DATA_HOME/forkd/snapshots/<tag>/. With --from-sandbox, leave unset to let the daemon auto-generate branch-<sandbox-id>-<unix-ts>. Required on the local-boot path. Must match [A-Za-z0-9_][A-Za-z0-9._-]{0,63}.Sandbox ID to branch from. When set, calls the daemon branch endpoint instead of booting a local parent VM. Requires
--daemon-url and optionally --daemon-token.Use v0.3 Diff snapshot mode (only with
--from-sandbox). Source pause is ~200 ms vs seconds for Full. Mutually exclusive with --live.Use v0.4 Live (UFFD_WP-based) BRANCH mode (only with
--from-sandbox). Source pause drops to sub-50 ms; memory is streamed asynchronously from the running parent after it resumes. Requires the source sandbox to have been created with --live-fork. Mutually exclusive with --diff. Requires Linux ≥ 5.7 and the vendored Firecracker fork.With
--live: return as soon as the source VM resumes (~10 ms) instead of waiting for the background memory copy to finish. The snapshot reaches status: ready later — poll GET /v1/snapshots or forkd ls --snapshots. Requires --live.Controller daemon base URL. Used when
--from-sandbox is set. Also read from the FORKD_URL environment variable.Bearer token for the controller daemon. Read from
FORKD_TOKEN when unset.Path to the
vmlinux kernel image. Required on the local-boot path (unless --from-sandbox is set). Also read from FORKD_KERNEL.Path to the rootfs image. Pass
.ext4 for read-write, or .squashfs for read-only. Required on the local-boot path (unless --from-sandbox is set). Also read from FORKD_ROOTFS.Mount the rootfs read-write. Auto-enabled when
--rootfs has a .ext4 extension.Host tap device name to attach as the guest’s
eth0 (e.g. forkd-tap0). Create with sudo bash scripts/host-tap.sh. Also read from FORKD_TAP.Seconds to wait for the guest to settle after boot before taking the snapshot. Increase for memory-intensive warmup workloads (browser recipes, LLM model loading).
Parent VM memory size in MiB. Defaults to 512 (set by
BootConfig). Override for memory-hungry warmup workloads: browser recipes need ≥2048, large SciPy / LLM warmups may need more.Keep
/tmp/forkd-parent-<tag>/ after the snapshot completes (default: removed). Useful for inspecting the parent VM console log post-snapshot.Attach a persistent volume to every child forked from this snapshot. Format:
HOST_FILE:GUEST_PATH[:ro]. Repeatable for up to 24 volumes (vdb..vdy). The host file must be an existing ext4 image. Use volumes for pip caches, model weights, or agent scratch space — content survives across forks of the same tag.forkd snapshot-diff
Derive a new diff snapshot from a base tag by running an installer command inside a transient one-shot sandbox. This is the primary tool for building v0.5 snapshot chains without manually managing sandboxes.
What it does:
- Spawns one sandbox from
--fromviaPOST /v1/sandboxes. - Waits up to 30 s for the guest agent to respond.
- Runs
--execvia the agent’s exec endpoint (with--exec-timeout-secsdeadline). - Issues a Diff BRANCH with
parent_tagset to record the chain edge:POST /v1/sandboxes/<id>/branchwithmode: "diff"andparent_tag: <from>. - Kills the transient sandbox unconditionally on both success and error paths.
parent_tag pointing at --from and a parent_content_hash that pins the parent’s memory bytes. The daemon verifies this hash at spawn time so re-snapshotting the base under the same tag fails loudly rather than silently restoring wrong bytes.
Base snapshot tag to derive from. Must already be registered with the daemon (check with
forkd images or GET /v1/snapshots).Tag for the new diff snapshot. Must not already exist. Must match the tag format rules.
Shell command to run in the spawned sandbox to produce the delta. Shell-split on whitespace with basic quote handling (single and double quotes supported). Example:
--exec "pip install pandas==2.0.0".Maximum wall-clock seconds for the exec step. Long installs like
pip install torch can approach this limit — increase as needed.Controller daemon base URL. Also read from
FORKD_URL.Bearer token for the controller daemon. Also read from
FORKD_TOKEN.forkd from-image
Build a forkd snapshot from a Docker image in a single pipeline step. Wraps forkd parent build (Docker → ext4) followed by forkd snapshot (boot + warmup + pause + register tag). After this completes, the snapshot is ready to fork from.
Docker image reference (positional argument). Examples:
python:3.12-slim, ghcr.io/user/repo:tag, registry.example.com/foo:bar.Forkd snapshot tag to register the result under.
Extra apt packages to install into the rootfs. Repeatable.
Rootfs image size in MiB.
Cache directory for built rootfs
.ext4 files. Re-running with the same image skips the Docker → ext4 step when the cached file exists. Also read from FORKD_RUN_CACHE.Kernel image path. When unset, searches
./vmlinux-6.1.141, ./vmlinux, /var/lib/forkd/kernels/vmlinux, and /usr/local/share/forkd/vmlinux. Also read from FORKD_KERNEL.Host tap device for the boot warmup. Also read from
FORKD_TAP.Seconds to wait for the guest to settle after boot before snapshotting.
Parent VM memory size in MiB. Defaults to 512 (set by
BootConfig).forkd rmi
Remove one or more snapshot tags. Tries DELETE /v1/snapshots/:tag on the daemon first (cleanly removes both registry entry and on-disk files atomically). Falls back to direct disk removal if the daemon is not running or returns 404.
One or more snapshot tags to remove (positional, variadic).
Delete this snapshot and every snapshot chained off it (and their descendants). Use before removing a chain parent to avoid orphaning children. Mutually exclusive with
--force.Delete this snapshot even if it would orphan child snapshots (breaks the chain — children become un-restorable). Mutually exclusive with
--cascade.Controller daemon base URL. Also read from
FORKD_URL.Bearer token for the controller daemon. Also read from
FORKD_TOKEN.- Without
--cascadeor--force, the daemon returns HTTP 409 if the snapshot has dependents in a chain. Useforkd snapshot-info <tag>first to see which children would be orphaned. - The disk fallback validation is stricter than the full tag format: only alphanumeric characters, dashes, and underscores are accepted (1–64 chars) to prevent path traversal without the daemon’s validator.
forkd snapshot-info
Show chain information for a snapshot by calling GET /v1/snapshots/:tag/info. Displays the parent chain, dependents, and on-disk sizes. Use this before rmi-ing a chained snapshot to see which children you would orphan.
Snapshot tag to query (positional argument).
Print the daemon’s raw JSON response body instead of the human-formatted table.
Controller daemon base URL. Also read from
FORKD_URL.Bearer token. Also read from
FORKD_TOKEN.forkd snapshot-compact
Flatten a chained snapshot into a new base snapshot by calling POST /v1/snapshots/:tag/compact. The daemon resolves the full ancestor chain, verifies parent content hashes, assembles the complete memory image, and writes a new flat snapshot with parent_tag: null. The new tag restores via the original non-chain path — useful when chain depth has grown enough that the per-link SHA-256 verification at spawn time is adding measurable latency.
Source snapshot tag (the chain head to flatten).
Tag for the new flat snapshot. Must not already exist. Must differ from
--from.Controller daemon base URL. Also read from
FORKD_URL.Bearer token. Also read from
FORKD_TOKEN.