Skip to content

Snapshots

A snapshot is a frozen VM state — kernel, root filesystem, memory, and CPU registers. When a session starts, the worker copies the disk (copy-on-write) and resumes the VM from the snapshot. Boot time is under 1 second.

paws ships with six snapshot templates. Each one builds on a minimal Ubuntu base with SSH, git, and curl pre-installed.

TemplateWhat’s includedRequired domains
minimalBase OS + SSH + gitNone
nodeNode.js 22 LTS + npmregistry.npmjs.org, nodejs.org
pythonPython 3.12 + pip + venvpypi.org, files.pythonhosted.org
dockerDocker CE + Compose pluginDocker registries
fullstackDocker + Node.js + BunDocker registries + npm + Bun
claude-codeNode.js + Claude Code CLI + jq + ripgrepapi.anthropic.com, claude.ai, npm

When you reference a template in your daemon config (e.g., "snapshot": "claude-code"), the worker restores from that template’s snapshot.

Use the snapshot config API to create a config, then trigger a build:

Terminal window
# Create a snapshot config from a template
curl -X POST "$PAWS_URL/v1/snapshot-configs" \
-H "Authorization: Bearer $PAWS_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "my-node-snapshot",
"template": "node",
"setup": "npm install -g typescript eslint",
"resources": { "vcpus": 2, "memoryMB": 4096 }
}'
# Trigger the build
curl -X POST "$PAWS_URL/v1/snapshots/my-node-snapshot/build" \
-H "Authorization: Bearer $PAWS_KEY"

The setup field is a bash script that runs inside a fresh VM. When the template field is set, the template’s setup script runs first, then your custom setup script runs on top.

You can skip templates entirely and provide a full setup script:

Terminal window
curl -X POST "$PAWS_URL/v1/snapshot-configs" \
-H "Authorization: Bearer $PAWS_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "ml-workbench",
"setup": "apt-get update && apt-get install -y python3 python3-pip && pip3 install torch transformers",
"requiredDomains": ["pypi.org", "files.pythonhosted.org", "huggingface.co"],
"resources": { "vcpus": 4, "memoryMB": 8192 }
}'

The requiredDomains field tells paws which domains the setup script needs to reach during the build process. These are automatically added to the proxy allowlist for the build session.

Each snapshot produces four files:

FileSize (typical)Purpose
vmlinux~40 MBLinux kernel
disk.ext4~2-4 GBRoot filesystem
memory.snap~4 GBFull memory state
vmstate.snap~30 KBCPU register state

On restore, the disk is copied with cp --reflink=auto (instant on btrfs/xfs, fast copy on ext4). The memory and vmstate are loaded directly by Firecracker.

In multi-node deployments, snapshots are distributed to workers via Cloudflare R2. When a snapshot is built (or rebuilt), it’s uploaded to R2. Each worker runs a sync loop that checks for new versions and pulls them automatically.

Configure sync on the worker:

Terminal window
SNAPSHOT_SYNC_ENABLED=true
R2_ENDPOINT=https://your-account.r2.cloudflarestorage.com
R2_ACCESS_KEY_ID=your-key
R2_SECRET_ACCESS_KEY=your-secret
R2_BUCKET_NAME=paws-snapshots
SNAPSHOT_SYNC_INTERVAL_MS=300000 # 5 minutes

The sync loop compares a local manifest against R2, downloads changed files to a temp directory, then atomically swaps the snapshot directory. Running VMs are not affected — they use their own copy-on-write disk copy.

  • Snapshots are checksummed (SHA-256) on build
  • Workers verify checksums before restoring
  • Snapshot files are read-only on the host
  • Each session gets a CoW disk copy — VMs cannot modify the base snapshot