Caches and snapshots¶
Save installed software or files so another sandbox can start from them:
from sandweave import Sandbox
with Sandbox() as env:
env.files.write_text("/workspace/note.txt", "saved state")
baseline = env.cache("my-workbench")
with Sandbox(cache="my-workbench") as env:
print(env.files.read_text("/workspace/note.txt"))
Caches save filesystem state by default. A restore starts fresh processes with independent writable state. It also restores the template's services and controls, so you do not need to specify the template again.
Saving first captures into the worker's local directory, then publishes a copy
under its persistent snapshot storage. Background verification removes the
local staging copy after the published files pass verification. Restores use
the published files even while verification is pending, so cleanup does not
interrupt them. Failed verification retains staging for recovery; diagnostic
--local-only captures are also retained.
Filesystem capture pauses the sandbox for a consistent cut of all its persistent mounts, then resumes it before publication and checksum verification. Runtime 2026.09.26.5 batches archive writes and reuses copy buffers, reducing overhead for filesystems with many small files. The archive format is unchanged.
Exports have a ten-minute no-progress limit per mount, rather than a fixed
total duration. Large exports can continue while the archive grows. To change
this limit, set SANDWEAVE_SNAPSHOT_STALL_TIMEOUT to positive seconds in the
worker's environment before starting it; for example, 1800 allows thirty
minutes without output progress. This setting applies to filesystem capture,
including caches, and does not change transport or restore startup deadlines.
Restore startup timeout¶
Use startup_timeout to allow a large snapshot more time to restore:
The default is 300 seconds. This is one total creation budget, shared by boot staging, unpacking all saved mounts (including Docker and containerd), and service readiness. Starting a new restore phase does not reset it. Since 0.2.39, these phases respect the requested budget instead of imposing separate 300-second staging and 600-second per-mount limits.
The same option works with cache=, Pool(..., startup_timeout=1800), and Weave
targets. For the CLI:
Upgrade the worker to 0.2.39 or newer; no image or engine rebuild is needed.
Timeout or cancellation aborts the incomplete restore and retains the saved
snapshot for retry. SANDWEAVE_SNAPSHOT_STALL_TIMEOUT still controls saves only.
Pin a particular version¶
A cache name can point to a newer revision later. Use the returned reference to reuse exactly the version you saved:
A missing cache raises CacheMiss. It does not silently build a replacement.
On a cluster, use the same cluster target when creating and restoring the cache.
Save Docker storage¶
The docker template starts with empty Docker and containerd storage. Images,
containers and named volumes are included when saving its filesystem:
with Sandbox(template="docker") as env:
env.run("docker pull busybox:1.37.0", timeout=180, check=True)
baseline = env.cache("docker-ready")
with Sandbox(cache="docker-ready") as env:
print(env.run("docker image ls", check=True).stdout)
Each restore has independent storage. A filesystem restore starts fresh
processes; use docker start for saved containers without an automatic restart
policy. The saved files are crash-consistent: application buffers held only in
RAM are not included. Memory checkpoints also save supported running processes.
Custom templates can set runtime_options.docker_data = true to create the same
checkpointed storage mounts. The Docker template enables this by default.
Its overlay2 driver needs these separate writable filesystems; a custom
template that disables them must provide compatible storage for its driver.
docker_archive optionally seeds those mounts from an immutable installation
asset on first launch; restoring a checkpoint uses its saved data and does not
require or reimport that archive.
Reuse setup automatically¶
from sandweave import Sandbox
with Sandbox(setup="./install-tools.sh", cache_key="tools-build") as env:
print(env.run("python --version").stdout)
Provide your own setup script. cache_key prepares a recipe and reuses its saved
result when the template, script, and declared inputs match. A change to those
inputs creates a new revision. cache loads an existing saved state directly.
Pause and resume¶
Pause keeps the same environment resident, including memory and GPU state. It does not release the runtime's memory reservation or save a durable checkpoint.
Checkpoint memory¶
from sandweave import Sandbox
with Sandbox() as env:
env.files.write_text("/workspace/note.txt", "saved state")
checkpoint = env.snapshot(state="memory")
if checkpoint.verify()["status"] != "passed":
raise RuntimeError("Checkpoint verification failed")
with Sandbox(snapshot=checkpoint) as restored:
print(restored.files.read_text("/workspace/note.txt"))
A supported gVisor memory snapshot saves process and kernel state as well as files. Verification can run asynchronously; the example checks it before attempting a restore. External services and shared volumes do not roll back.
During gVisor snapshot publication and transfer, Sandweave reuses checksums for
files whose recorded identity and timestamps still match. New copies are checked
before publication. Calling checkpoint.verify() explicitly rechecks the bytes.
Save before stopping¶
env = Sandbox()
saved = env.stop()
env.close()
with Sandbox(snapshot=saved) as restored:
print(restored.run("python --version").stdout)
stop() saves before releasing the runtime. A failed save keeps the source
running. Use terminate() when you want to discard unsaved state instead.
GPU and native runtime support¶
GPU filesystem caches start fresh GPU processes. Ordinary live graphics state
cannot be restored. CUDA-only memory restoration is experimental and needs
experimental_gpu_live=True at capture and restore.
Native Apptainer supports filesystem caches, but not memory snapshots. See resources for runtime differences.