NodeOps
UK

How-to: manage sandbox lifecycle

Recipes for pausing, resuming, forking, recharging bandwidth, and destroying sandboxes. For the underlying concepts — state machine, billing model, fork semantics — see Lifecycle.


At a glance

  • Package: @nodeops-createos/sandbox (npm)
  • Import: import { createClient } from "@nodeops-createos/sandbox"
  • Base URL: https://api.sb.createos.sh — override with CREATEOS_SANDBOX_BASE_URL
  • Auth: API key via the apiKey option or CREATEOS_SANDBOX_API_KEY

Pause to stop billing, resume later

Problem

You want to preserve a sandbox's disk and memory state between tasks without paying for idle compute time.

Solution

Call pause() and confirm the transition with waitUntilPaused(). The sandbox snapshot is stored; billing for compute stops. When you need it back, call resume() and wait with waitUntilRunning().

TypeScript
1import { CreateosSandboxClient } from "@nodeops-createos/sandbox";
2
3const client = new CreateosSandboxClient();
4const sandbox = await client.createSandbox({ shape: "s-4vcpu-4gb", rootfs: "devbox:1" });
5
6try {
7 // ... do work ...
8
9 // Snapshot and suspend. The handle transitions to pausing → paused.
10 await sandbox.pause();
11 await sandbox.waitUntilPaused();
12 console.log("paused:", sandbox.status); // "paused"
13
14 // Later — restore. The handle transitions to resuming → running.
15 await sandbox.resume();
16 await sandbox.waitUntilRunning();
17 console.log("running:", sandbox.status); // "running"
18
19 // ... continue work ...
20} finally {
21 await sandbox.destroy();
22}

pause() throws CreateosSandboxValidationError if the sandbox is not in a pausable state (e.g. already pausing or destroyed). Both pollers accept a timeoutMs option:

TypeScript
1await sandbox.waitUntilPaused({ timeoutMs: 30_000 });

Auto-pause an idle sandbox

Problem

You want the control plane to pause the sandbox automatically when it sits idle, without the client polling for idleness itself.

Solution

Set auto_pause_after_seconds at create time, or update it on a live sandbox with setAutoPause(seconds). Pass null to disable.

TypeScript
1import { CreateosSandboxClient } from "@nodeops-createos/sandbox";
2
3const client = new CreateosSandboxClient();
4
5// Option A — bake the timeout in at create. Valid range: 60–86400 (1 min – 24 h).
6const sandbox = await client.createSandbox({
7 shape: "s-4vcpu-4gb",
8 rootfs: "devbox:1",
9 auto_pause_after_seconds: 300, // pause after 5 min idle
10});
11
12try {
13 // Option B — change the timeout on a running sandbox.
14 await sandbox.setAutoPause(600); // update to 10 min
15 console.log("timeout:", sandbox.data.auto_pause_after_seconds); // 600
16
17 // Disable auto-pause entirely.
18 await sandbox.setAutoPause(null);
19 console.log("timeout:", sandbox.data.auto_pause_after_seconds ?? "off"); // "off"
20} finally {
21 await sandbox.destroy();
22}

setAutoPause refreshes the handle in place, so sandbox.data.auto_pause_after_seconds reflects the new value immediately after the call returns.

The server rejects values outside 60–86400 with CreateosSandboxValidationError. When the idle timeout fires, the control plane pauses the sandbox exactly as if you had called pause() — compute billing stops, disk and memory state are preserved.


Fork (branch) a sandbox

Problem

You want to create one or more independent copies of a sandbox from a known checkpoint — for example to run parallel experiments from the same base state.

Solution

Pause the sandbox (fork requires paused state), then call fork(). Each call returns a handle to a new, fully independent sandbox. The parent stays paused; you can fork from it again or resume it independently.

TypeScript
1import { CreateosSandboxClient } from "@nodeops-createos/sandbox";
2
3const client = new CreateosSandboxClient();
4const parent = await client.createSandbox({ shape: "s-4vcpu-4gb", rootfs: "devbox:1" });
5let branchA: Awaited<ReturnType<typeof parent.fork>> | undefined;
6let branchB: Awaited<ReturnType<typeof parent.fork>> | undefined;
7
8try {
9 // ... install deps, set up state ...
10
11 // Pause parent before forking.
12 await parent.pause();
13 // Fork can occasionally stick in a pausing state on the control plane —
14 // always wait for paused before relying on the fork.
15 await parent.waitUntilPaused();
16
17 // Fork two independent branches from the same checkpoint.
18 branchA = await parent.fork(); // auto-resumes
19 branchB = await parent.fork(); // auto-resumes
20
21 await branchA.waitUntilRunning();
22 await branchB.waitUntilRunning();
23
24 // The branches are independent — changes in one do not affect the other.
25 console.log("branch A:", branchA.id);
26 console.log("branch B:", branchB.id);
27 console.log("parent still paused:", parent.status); // "paused"
28
29 // ... run experiments on branchA and branchB concurrently ...
30} finally {
31 await Promise.allSettled([
32 branchA?.destroy(),
33 branchB?.destroy(),
34 parent.destroy(),
35 ]);
36}

To keep a fork paused instead of auto-resuming, pass start_paused: true:

TypeScript
1const clone = await parent.fork({ start_paused: true });
2// clone.status === "paused"

fork() throws CreateosSandboxValidationError if the source sandbox is not in a forkable state. The source must be paused before forking.


Grow bandwidth quota after create

Problem

You want to raise a running sandbox's egress cap — either proactively or because BandwidthView.capped is true.

Solution

Read the current quota with getBandwidth(), then add bytes with rechargeBandwidth(addBytes).

TypeScript
1import { CreateosSandboxClient } from "@nodeops-createos/sandbox";
2
3const GiB = 1024 ** 3;
4
5const client = new CreateosSandboxClient();
6const sandbox = await client.createSandbox({ shape: "s-4vcpu-4gb", rootfs: "devbox:1" });
7
8try {
9 const bw = await sandbox.getBandwidth();
10 console.log(`quota: ${bw.quota_bytes} used: ${bw.used_bytes} capped: ${bw.capped}`);
11
12 if (bw.capped) {
13 const updated = await sandbox.rechargeBandwidth(10 * GiB); // +10 GiB
14 console.log(`new quota: ${updated.quota_bytes}`);
15 }
16} finally {
17 await sandbox.destroy();
18}

bandwidth_quota_bytes is not settable at create time. The server rejects non-zero values at create with a 400. Use rechargeBandwidth() post-create as the only supported path to grow the cap. quota_bytes === -1 means unmetered; rechargeBandwidth is a no-op on unmetered sandboxes.


Destroy and confirm

Problem

You want to tear down a sandbox and be certain the resource has been fully reclaimed before proceeding.

Solution

destroy() is async server-side: the call returns when the row reaches destroying, but reclamation may still be in progress. Use waitUntilDestroyed() to block until the row is fully reclaimed.

TypeScript
1import { CreateosSandboxClient } from "@nodeops-createos/sandbox";
2
3const client = new CreateosSandboxClient();
4const sandbox = await client.createSandbox({ shape: "s-4vcpu-4gb", rootfs: "devbox:1" });
5
6try {
7 // ... do work ...
8} finally {
9 const result = await sandbox.destroy();
10 // result.status is "destroying" | "destroyed"
11
12 // Block until fully reclaimed if needed (e.g. in tests, or before reusing
13 // the same name/slot).
14 await sandbox.waitUntilDestroyed();
15 console.log("reclaimed:", sandbox.status); // "destroyed"
16}

waitUntilDestroyed() treats destroying as an intermediate step and does not abort on it — only error and failed states cause it to throw.


Pause vs. fork

Pause suspends the same sandbox. Its id is unchanged. Resume picks up exactly where it left off. Use it to stop billing between sessions.

Fork creates a new, independent sandbox from the paused snapshot. The parent keeps its id and stays paused. Use it to branch experiments or spin up parallel workloads from a shared base.

For deeper treatment of the state machine and billing model, see Lifecycle.


See also

  • Reference: Sandbox — full method signatures and parameter tables for pause, resume, fork, destroy, setAutoPause, getBandwidth, rechargeBandwidth, and the waitUntil* pollers.

100,000+ Builders. One Workspace.

Get product updates, builder stories, and early access to features that help you ship faster.

CreateOS is a unified intelligent workspace where ideas move seamlessly from concept to live deployment, eliminating context-switching across tools, infrastructure, and workflows with the opportunity to monetize ideas immediately on the CreateOS Marketplace.