# How to label and list sandboxes Pass `labels: { team: "search" }` when you create a sandbox, then `runtime.sandboxes.list({ labels })` returns every sandbox that matches. **On Runtime every list, in every product, returns the same page object, and one loop walks every page.** A sandbox takes up to 32 `key: value` labels, so a CI run, a customer or an agent task can find and clean up exactly its own sandboxes. A paid account holds 100 sandboxes at once to start, running or paused ([pricing](/docs/pricing#how-many-at-once), checked 25 September 2026). ## Label at create, filter when you list ```ts import { Runtime } from "withruntime"; const runtime = new Runtime(); const sbx = await runtime.sandboxes.create({ labels: { team: "search", job: "42", ci: "true" }, }); const page = await runtime.sandboxes.list({ labels: { team: "search" }, state: ["running"] }); for await (const found of page) console.log(found.id, found.info.name, found.state); await sbx.stop(); ``` ```python from withruntime import Runtime runtime = Runtime() sbx = runtime.sandboxes.create(labels={"team": "search", "job": "42", "ci": "true"}) for found in runtime.sandboxes.list(labels={"team": "search"}, state=["running"]): print(found.id, found.info["name"], found.state) sbx.stop() ``` ```bash id=$(runtime sandbox create --name demo --label team=search --label job=42) runtime sandbox ls runtime sandbox get "${id}" runtime sandbox stop "${id}" ``` `--label k=v` repeats on `runtime sandbox create`. `runtime ls` lists everything the account runs, across every product, not only sandboxes. ## Clean up after a CI run Label each sandbox with the run's id, and stop whatever is left when the run ends, even after a failure: ```ts import { Runtime } from "withruntime"; const runtime = new Runtime(); const run = process.env.GITHUB_RUN_ID ?? "local"; await runtime.sandboxes.create({ labels: { ci: run } }); for await (const leftover of await runtime.sandboxes.list({ labels: { ci: run } })) await leftover.stop(); ``` ```python import os from withruntime import Runtime runtime = Runtime() run = os.environ.get("GITHUB_RUN_ID", "local") runtime.sandboxes.create(labels={"ci": run}) for leftover in runtime.sandboxes.list(labels={"ci": run}): leftover.stop() ``` ## Change labels later ```ts check import { Sandbox } from "withruntime"; const sbx = await Sandbox.create({ labels: { team: "search" } }); await sbx.update({ labels: { team: "search", owner: "ada" } }); ``` ```bash no-run runtime sandbox update "${id}" --name dev-2 --label team=search ``` ## Filters and paging | Filter or field | What it does | | ----------------- | ------------------------------------------------------------------------- | | `labels` | Every label given must match; over HTTP, repeat `label=key:value` | | `state` | Such as `["running"]` or `["paused"]` | | `name` | The one live sandbox with that name | | `includeStopped` | Stopped sandboxes are left out unless this is `true` | | `limit`, `cursor` | Page size and the next page, over HTTP | | The page | `page.data`, `page.hasMore`, `page.next()`, `page.toArray()`, `for await` | | Python page | `page.data`, `page.has_more`, `page.next_page()`, `page.to_list()`, `for` | | Label limit | Up to 32 `key: value` labels a sandbox | | MCP | `runtime_sandbox_list` by state, name or label, or one by id | | Cost | Listing and labels cost nothing | ## Mistakes to avoid - **Reading only the first page.** `page.data` is one page. Loop with `for await` (or `for` in Python), or call `toArray()`, to reach every match. - **Expecting stopped sandboxes in the list.** They are left out by default. Pass `includeStopped: true` to audit what ran. - **Putting secrets or personal data in labels.** Labels are for finding things, and anyone with a read-only key on the account can list them. Keep secrets in `env` or in [Runtime secrets](/docs/security#secrets-sandboxes-never-see). - **Using a label as a unique handle.** Many sandboxes can share a label. For exactly one, use a [name](/how-to/find-a-sandbox-by-name). - **Leaving cleanup to luck.** A sandbox's lease pauses it when time runs out, and a paused sandbox still counts toward the account's 100. Stop by label at the end of each job. ## Related - [Find a sandbox by name](/how-to/find-a-sandbox-by-name) for one handle per sandbox. - [Agent evals and SWE-bench](/use-cases/agent-evals-and-swe-bench), where each run labels its sandboxes. - [Keep a sandbox running](/how-to/keep-a-sandbox-running) for sandboxes you do not want cleaned up. - [Find sandboxes again](/docs/javascript#find-sandboxes-again) in the SDK reference. Facts on this page were checked on 25 September 2026.