Snapshots and environments
Copy a sandbox, save its disk, share it with another team, and start with saved variables
Four ways to start a sandbox that is ready to work, instead of setting it up every time.
Copy a sandbox
fork starts a new sandbox with a copy of the source's disk. The source keeps running. The copy keeps its size, timeout, name and metadata, and is billed like any start: $0.01, then machine time.
const { sandbox: copy } = await zavu.sandboxes.fork(sandboxId);
console.log(copy.id, copy.forkedFromSandboxId);
The source must be running or stopped, and not ephemeral.
Save a snapshot
A snapshot freezes a sandbox's disk under a name, so you can start any number of sandboxes from it later. A running sandbox is captured as it is now; a stopped one as it was when it stopped.
const { snapshot } = await zavu.sandboxes.snapshots.create({
sandboxId,
name: "node-22-with-deps",
});
// The save runs in the background.
let current = snapshot;
while (current.status === "saving") {
await new Promise((r) => setTimeout(r, 5000));
({ snapshot: current } = await zavu.sandboxes.snapshots.retrieve(snapshot.id));
}
// Start from it. The sandbox takes the snapshot's size.
const { sandbox } = await zavu.sandboxes.create({ from: snapshot.id });
- A snapshot costs $0.07 per started UTC day while you keep it. The first day is charged when you save, and returned if the save fails.
- A team keeps at most 20. Delete one with
zavu.sandboxes.snapshots.delete(id); sandboxes already started from it keep their disk. - Starting from a snapshot that is still saving answers
409 snapshot_not_ready. An ephemeral sandbox cannot be saved.
Share a snapshot
A share code lets another team start from your snapshot. They pay their own start and machine time; you keep paying for the snapshot.
const { snapshot } = await zavu.sandboxes.snapshots.share(snapshotId);
console.log(snapshot.shareCode); // zsh_k3m4n5p6q7r2s3t4u5v6w7x2y3z4a5b6
// The other team:
await zavu.sandboxes.create({ from: "zsh_k3m4n5p6q7r2s3t4u5v6w7x2y3z4a5b6" });
// Stop sharing:
await zavu.sandboxes.snapshots.revokeShare(snapshotId);
Asking again returns the same code until it is revoked. A revoked code, or one of a deleted snapshot, answers 404 not_found on create, and nothing is charged. Sandboxes already started from it keep their disk.
Environments
An environment is a named set of variables your project keeps, so you do not send secrets on every create. Values are stored encrypted and never returned: reads show each variable's name and its last four characters.
const { environment } = await zavu.sandboxes.environments.create({
name: "staging",
env: { DATABASE_URL: "postgres://user:pass@db/app", API_TOKEN: "tok_123" },
});
// Start with it. Variables in `env` win on the same name.
await zavu.sandboxes.create({ environment: "staging", env: { DEBUG: "1" } });
// Add or replace some variables, remove others. The rest keep their values.
await zavu.sandboxes.environments.update(environment.id, {
env: { FEATURE_FLAG: "1" },
unset: ["API_TOKEN"],
});
- A name is 1 to 64 letters, digits, dots, dashes or underscores, unique in the project. A project keeps at most 50.
- Variables follow the
envrules: names match[A-Za-z_][A-Za-z0-9_]{0,127}, at most 100 per sandbox and 64 KB in total, countingenvand the environment together. - Changing or deleting an environment does not touch sandboxes already started with it.
- An unknown name on create answers
404 not_found, and nothing is charged.