# Sandbox Lifecycle
source: https://docs.chalk.ai/docs/sandboxes/lifecycle

## The stages a Chalk sandbox goes through, and how to inspect its status and terminate it.

Sandboxes follow a straightforward lifecycle:

- Image resolution. If the image is an Image spec (e.g. Image.debian_slim().pip_install([...])), it is built and cached. Pre-built OCI images are used directly.
- Scheduling. The sandbox is placed on a node with sufficient resources. gVisor initializes the isolation boundary.
- Running. The sandbox accepts exec calls. Volumes are mounted and accessible.
- Termination. The sandbox is terminated explicitly or after its lifetime expires. Ephemeral filesystem state is discarded; volume data persists if synced.

```
from chalkcompute import Image, Sandbox

sandbox = Sandbox(
    image=Image.debian_slim().pip_install(["numpy"]),
    cpu="2",
    memory="4Gi",
    lifetime="3600s",
).run()

result = sandbox.exec("python", "-c", "import numpy; print(numpy.__version__)")
print(result.stdout_text)

sandbox.terminate()
```

lifetime is a protobuf duration string — a number of seconds followed by
s (fractional seconds are allowed, e.g. "1.5s"), not a Go-style duration
like "1h". Omitting it lets the sandbox run until it is terminated
explicitly; see Long-running sandboxes for runs
measured in hours or days.

### Inspecting status

sandbox.info is None until the sandbox has been started or attached to.
sandbox.refresh() both refreshes and returns the current SandboxInfo, so
prefer its return value over sandbox.info when you've just refreshed:

```
info = sandbox.refresh()
print(info.status)  # "pending", "running", "succeeded", "failed", etc.
print(sandbox.id)
```

### Terminating

```
sandbox.terminate()                          # immediate termination + cleanup
sandbox.terminate(grace_period_seconds=30)   # allow processes to shut down first
```

Termination cleans up the sandbox and its ephemeral filesystem. Persistent volume
data remains available according to the volume's sync and versioning semantics.





