---
title: "Sandbox SDK lifecycle"
canonical: https://trickest.com/docs/developer-tools/sandbox-sdk/lifecycle
description: "Create persistent sandboxes, stop and resume them, and delete environments when work ends."
---

# Sandbox SDK lifecycle

`Sandbox.create()` defaults `persistent` to `true`. Set it explicitly when your application needs to resume work later.

## Choose the end of the lifecycle

| Operation                                       | Result                                                                                           |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `Sandbox.create({ token, persistent: true })`   | Request an environment that can retain its working directory through stop/resume |
| `sandbox.stop()`                                | Stop compute; a persistent environment can resume, while a non-persistent environment terminates |
| `Sandbox.get({ token, id })`                    | Retrieve the environment, automatically resuming a stopped persistent sandbox                    |
| `Sandbox.get({ token, id, autoResume: false })` | Inspect recorded state without requesting auto-resume                                            |
| `sandbox.delete()`                              | Retire the sandbox permanently; it cannot resume                                                 |

Keep the returned `sandboxId` to retrieve the environment later. You can also
look it up by name. A handle's `status` is cached, not a live feed. `stop()`
refreshes that handle after its request; use `Sandbox.get()` for a fresh read.

## Stop and resume the same environment

This example writes a marker, stops the environment, resumes it by ID, and checks the retained file. It deletes the sandbox when the check finishes.

```typescript
import { Sandbox } from "@trickest/sandbox";

export async function checkRetainedWork(token: string): Promise<void> {
  const sandbox = await Sandbox.create({
    token,
    runtime: "node24",
    persistent: true,
    timeout: 5 * 60_000,
  });
  try {
    await sandbox.writeFile("progress.txt", "step one complete");
    await sandbox.stop();

    const paused = await Sandbox.get({
      token,
      id: sandbox.sandboxId,
      autoResume: false,
    });
    console.log("Recorded state:", paused.status);

    const resumed = await Sandbox.get({ token, id: sandbox.sandboxId });
    const progress = await resumed.readFileToBuffer({ path: "progress.txt" });
    if (progress === null) throw new Error("Retained progress is missing");
    console.log(new TextDecoder().decode(progress));
  } finally {
    await sandbox.delete();
  }
}
```

Retention covers the working directory at `/trickest/sandbox`, not the entire
guest or container filesystem. Files under other paths and system packages
installed outside that directory can disappear when the container is recreated.
Retention also depends on the sandbox remaining available. Running processes do
not survive stopping the machine; restart them after resuming.

The creation option `timeout` requests a sandbox lease window in milliseconds.
Server policy controls enforcement and may shorten that window.
`extendTimeout(durationMs)` requests a renewal; it does not promise that a
long-running command will keep the sandbox alive. It differs from a command's
`timeoutMs`, which limits the client's wait. Always clean up explicitly and
download results before final deletion.

Control-plane requests have separate client deadlines: five minutes for creation and 25 seconds for get/list and stop/delete/extend. Override them through `TRICKEST_SANDBOX_CREATE_TIMEOUT_MS`, `TRICKEST_SANDBOX_GET_TIMEOUT_MS`, and `TRICKEST_SANDBOX_OP_TIMEOUT_MS`. A timed-out request does not prove that its server-side operation stopped.

## Find environments without resuming them

`Sandbox.list()` is cursor-paginated and does not auto-resume stopped environments. A list page contains handles and `nextCursor`; it is not an async iterable.

```typescript
import { Sandbox } from "@trickest/sandbox";

export async function listEnvironmentIds(token: string): Promise<string[]> {
  const ids: string[] = [];
  let cursor: string | undefined;
  do {
    const page = await Sandbox.list({ token, limit: 50, cursor });
    ids.push(...page.items.map((sandbox) => sandbox.sandboxId));
    cursor = page.nextCursor ?? undefined;
  } while (cursor);
  return ids;
}
```

## Snapshot limitations

`snapshot()` rejects with `SandboxSnapshotUnsupportedError` before a network
call. `fork()` copies metadata and configuration, not the filesystem. The SDK
ignores a snapshot source and logs a warning. Do not use these methods for backups.

The [platform SDK's sessions](/docs/developer-tools/sdk/sandbox) have a separate workspace capture and disposal model. Their stop method is not the standalone persistent stop/resume contract described here.

---
_Markdown source of https://trickest.com/docs/developer-tools/sandbox-sdk/lifecycle._
