Skip to content

Snapshots and environments

Copy a sandbox, save its disk, share it with another team, and start with saved variables

View .md

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 env rules: names match [A-Za-z_][A-Za-z0-9_]{0,127}, at most 100 per sandbox and 64 KB in total, counting env and 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.