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.

Automatic cleanup

Automatic cleanup ties a sandbox’s lifetime to a Python construct (a context manager or the running process) so the SDK releases resources without explicit stop() calls. 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:
from cwsandbox import Sandbox

with Sandbox.run() as sandbox:
    result = sandbox.exec(["echo", "hello"]).result()
# sandbox.stop() called automatically
Sessions clean up all their sandboxes:
import cwsandbox
from cwsandbox import SandboxDefaults

with cwsandbox.Session(SandboxDefaults(container_image="python:3.11")) as session:
    sb1 = session.sandbox()
    sb2 = session.sandbox()
# Both sandboxes stopped automatically

Global cleanup handlers

For cases where a context manager isn’t practical, the SDK registers cleanup handlers that run when the process terminates:
ScenarioBehavior
Normal script exitatexit handler stops all sandboxes
Ctrl+C (SIGINT)Signal handler stops all sandboxes
SIGTERMSignal handler stops all sandboxes
Second Ctrl+CForce exit (prevents unresponsive shutdown)

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()

sandbox = Sandbox.run()
result = sandbox.exec(["echo", "hello"]).result()
sandbox.stop().result()

# With options
sandbox.stop(graceful_shutdown_seconds=30.0).result()
sandbox.stop(snapshot_on_stop=True).result()

Session close()

from cwsandbox import SandboxDefaults

session = cwsandbox.Session(SandboxDefaults(container_image="python:3.11"))
sandbox = session.sandbox()
# ...
session.close().result()  # Stops all sandboxes

Batch cleanup

from cwsandbox import results

sandboxes = [Sandbox.run() for _ in range(5)]
# ... use sandboxes ...
results([sb.stop() for sb in sandboxes])  # Stop all in parallel

Orphan management

Orphans are sandboxes that outlive the process that created them. 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

The SDK’s automatic cleanup handlers prevent most orphans. Sandboxes can keep running after forced shutdowns (kill -9), network failures, or when you create sandboxes outside of sessions and context managers. Use tags to make any orphans discoverable later.
from cwsandbox import Sandbox, SandboxDefaults

# Tag at creation time
defaults = SandboxDefaults(
    container_image="python:3.11",
    tags=("my-project", "batch-job-123"),
)

with Sandbox.run(defaults=defaults) as sandbox:
    result = sandbox.exec(["echo", "hello"]).result()
Good tagging practices:
  • 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:
from cwsandbox import Sandbox

orphans = Sandbox.list(tags=["my-project"]).result()
for sandbox in orphans:
    sandbox.stop().result()

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:
import cwsandbox
from cwsandbox import SandboxDefaults

with cwsandbox.Session(SandboxDefaults(container_image="python:3.11")) as session:
    orphans = session.list(tags=["my-project"]).result()
    for sandbox in orphans:
        session.adopt(sandbox)
# All adopted sandboxes cleaned up with session

Delete by ID

When you already know a sandbox’s ID, you can delete it directly without listing or adopting it first:
from cwsandbox import Sandbox

Sandbox.delete("sandbox-abc123").result()
Sandbox.delete("sandbox-abc123", missing_ok=True)  # Ignore if gone
Last modified on May 29, 2026