Skip to main content
This guide covers resource management and cleanup strategies for sandboxes. Reliable cleanup prevents orphaned sandboxes after a script exits, which keeps costs predictable and avoids unintentional compute resource usage. The patterns here apply to scripts that create one or many sandboxes, with or without an explicit session.

Choose authentication

These examples run on serverless capacity unless a section specifies CKS. Choose the credential for the account that owns your sandboxes. See Choose and get credentials to obtain a key or token. Run the installation commands in an active Python virtual environment. Save the Python code from your credential tab as sandbox_auth.py beside the Python scripts you run from this page. It stores the authentication choice, not your credential. The examples import AUTH from that file and pass it explicitly to each new sandbox or session.
Use your Forge API key through the SDK’s W&B authentication strategy:
sandbox_auth.py
For CKS placement, choose the CoreWeave token, enable a runner, and set placement_mode="cks" on sandbox creation or in SandboxDefaults. Creating a session with auth=AUTH also authenticates the sandboxes it owns. Keep the same credential when reconnecting, listing, or cleaning up sandboxes.

Automatic cleanup

Automatic cleanup ties a sandbox’s lifetime to a Python context manager or a session that the SDK closes when the process exits. The SDK releases resources without explicit stop() calls. A sandbox you start with Sandbox.run() outside a session or context manager can keep running after your script exits. It stops when its main command exits successfully (exit status 0), you stop it, or its maximum lifetime expires. A nonzero exit can trigger automatic container restarts. The sandbox fails if it reaches the restart limit. See Main command lifetime. Context managers are the recommended pattern because they guarantee cleanup even if the enclosed code raises an exception. The SDK stops sandboxes when the context exits:
Sessions clean up all their sandboxes:

Global cleanup handlers

The SDK registers cleanup handlers that stop sandboxes owned by registered sessions when the process terminates. Standalone sandboxes created outside a session or context manager require explicit cleanup: In cwsandbox>=1.15.0, cleanup handlers activate when the process first owns a sandbox. This includes standalone creation and session creation or adoption of a sandbox. Looking up an existing sandbox with Sandbox.from_id() alone doesn’t activate these handlers. The SIGINT and SIGTERM handlers install only from Python’s main thread. Activation on another thread registers atexit and leaves signal installation pending for later ownership on the main thread. If your application manages its own signals, call cwsandbox.disable_signal_handlers() or set CWSANDBOX_DISABLE_SIGNAL_HANDLERS=1 before you create the first sandbox. The atexit handler still runs, but your application must stop sandboxes when a signal arrives.

Manual cleanup

Use manual cleanup when you need explicit control over when to release a sandbox or session. Manual cleanup lets you pass stop options or coordinate cleanup across long-running code.

Sandbox stop()

Choose plain stop or snapshot-on-stop before shutdown begins. Each example creates a separate sandbox and waits for its command before stopping it. The context manager also attempts cleanup if the work or stop call raises an exception.
Stop without capturing a snapshot. This example allows 30 seconds for graceful shutdown and uses missing_ok=True to tolerate a sandbox that is already gone:
A snapshot_on_stop=True request raises SnapshotOnStopConflictError if a plain stop is already in progress or the sandbox has already stopped without a captured snapshot. Request the snapshot before plain cleanup begins. Repeated plain stops can share the same operation. See Stop a sandbox for stop behavior.

Session close()

When you close a session, it stops all sandboxes it owns:

Batch cleanup

The following example stops several sandboxes in parallel:

Orphan management

Orphans are sandboxes left running unintentionally after the process that created them exits. A standalone sandbox that you keep running on purpose isn’t an orphan, but it becomes one if you lose track of it. The following sections describe how to make orphans easy to find, how to query for them, and how to bring them back under managed cleanup.

Tagging for discovery

Use tags to make any orphans discoverable later. For sandboxes in sessions and context managers, the SDK’s automatic cleanup prevents most orphans. Those sandboxes can still keep running after forced shutdowns (kill -9) or network failures. The cleanup handlers never stop a standalone sandbox, so it becomes an orphan if you forget to stop it.
Use the following tags to make sandboxes discoverable:
  • Project or application name (my-project)
  • Job or run identifier (batch-job-123, run-2024-01-15)
  • Environment (dev, staging, prod)

Find orphaned sandboxes

Query by tags to find sandboxes from previous runs:

Session adoption

Adopting an orphan attaches it to a session so the session governs its lifetime. The orphan then receives the same automatic cleanup guarantees as newly created sandboxes. session.list() adds the session’s default tags to your filter, so it finds only sandboxes that carry them. To search without the session’s tags, use Sandbox.list() and adopt each result, as in the Sessions guide:

Stop by ID

To stop a sandbox whose ID you saved from an earlier run, reconnect with the same credential. Replace [SANDBOX-ID] with the sandbox ID:
If the sandbox disappears before the stop request, the missing_ok=True option suppresses SandboxNotFoundError. It doesn’t suppress a failed Sandbox.from_id() lookup. If the sandbox is already gone, that call still raises SandboxNotFoundError.

Delete by ID

To use options such as graceful_shutdown_seconds or snapshot_on_stop, call stop() on a sandbox instance. Sandbox.delete() deletes directly by ID without creating an instance. When you already know a sandbox’s ID, you can delete it without listing or adopting it first:
Last modified on November 6, 2026