Ephemeral — no name. Runs until you terminate it or it times out. Cannot be suspended.
Named — a name given at creation (or assigned later). Supports suspend and resume, so you can pause between tasks and pick up exactly where you left off.
Every sandbox moves through the states below. Create starts the sandbox in Pending; from Running, you can suspend (named only), snapshot, or terminate. Ephemeral sandboxes follow the same flow but skip Suspending/Suspended.
State
What it means
How you exit it
Pending
Sandbox is being scheduled and booted. Not yet ready to accept commands.
Transitions to Running automatically once boot completes.
Running
Sandbox is live and accepting commands, file operations, and process execution. Snapshots can be taken from this state.
Call suspend (named only) or terminate.
Snapshotting
A reusable snapshot artifact is being captured from the sandbox’s filesystem, memory, and running processes.
Returns to Running when capture completes.
Suspending
Named sandbox is being paused in place. Triggered by manual suspend or by timeout_secs elapsing.
Transitions to Suspended automatically.
Suspended
Named sandbox is paused. Consumes no compute; state is preserved for resume under the same sandbox ID.
Call resume to return to Running, or terminate to end it.
Terminated
Sandbox has stopped — manually, or via timeout for ephemeral sandboxes. Final state; cannot be reversed.
Create an ephemeral sandbox by calling create with no name. Add a name to make the sandbox persistent and eligible for suspend/resume.You can also boot a sandbox from an existing snapshot to restore a previously captured filesystem, memory, and running processes. See Restoring from a snapshot for details.
CLI
Python
TypeScript
HTTP
# Ephemeral — runs until terminated or timed outtl sbx create# Named — can be suspended and resumedtl sbx create my-env
from tensorlake.sandbox import Sandbox# Ephemeral sandbox — no name, cannot be suspendedephemeral = Sandbox.create()# Named sandbox — can be suspended and resumednamed = Sandbox.create(name="my-env")print(f"Sandbox ID: {named.sandbox_id}")print(f"Status: {named.status}")
// Ephemeral sandbox — no name, cannot be suspendedconst ephemeral = await Sandbox.create();// Named sandbox — can be suspended and resumedconst named = await Sandbox.create({ name: "my-env" });console.log(named.sandboxId, named.status);
Configure CPU, memory, and disk size per sandbox. These are fixed when the sandbox is created and cannot be changed afterwards — create a new sandbox if you need different resources.
Memory in megabytes. Must be between 1024–8192 MB per CPU core.
disk_mb
int
10240
Root filesystem size in MiB. Defaults to 10240 (10 GiB) when omitted. Must be between 10240 and 102400 (10–100 GiB). The CLI accepts --disk_mb in MiB. Accepted for fresh creates. With image, disk_mb can be used to grow the root disk at create time (growth-only). With snapshot_id from a filesystem snapshot, disk_mb can also be used to grow the root disk at restore time (growth-only).
Sandboxes run on Tensorlake’s managed Ubuntu 24.04 environment by default. If you need reusable setup or preinstalled dependencies, create a Sandbox Image and launch sandboxes with --image. For one-off startup setup, create the sandbox and then use command execution to run those steps explicitly.
You can assign or update a sandbox’s name after it is created. This is how you convert an ephemeral sandbox into a named one so it becomes eligible for suspend and resume.
CLI
Python
TypeScript
HTTP
# Assign a name to a running sandboxtl sbx name <sandbox-id> my-env# Change an existing nametl sbx name my-env new-name
from tensorlake.sandbox import Sandboxsandbox = Sandbox.create()named_sbx = sandbox.update(name="my-env")print(named_sbx.name)
Once a sandbox has a name, you can use either the name or the UUID anywhere a sandbox identifier is accepted. Use connect to get an operable handle from either identifier.
CLI
Python
TypeScript
HTTP
# All of these work with either the ID or the nametl sbx exec my-env python main.pytl sbx ssh my-envtl sbx cp ./file.py my-env:/workspace/file.pytl sbx suspend my-envtl sbx resume my-envtl sbx terminate my-envtl sbx checkpoint my-envtl sbx name my-env new-name
info = Sandbox.connect("my-env")print(info.status)sandbox = Sandbox.connect(identifier="my-env")print(sandbox.sandbox_id) # server UUID, e.g. "s7jus08qec4axzgbpq76h"print(sandbox.name) # "my-env"result = sandbox.run("python", ["main.py"])print(result.stdout)renamed = sandbox.update(name= "new-name")print(renamed.name)sandbox.terminate()
const info = await Sandbox.connect("my-env");console.log(info.status);const sandbox = Sandbox.connect("my-env");console.log(sandbox.sandboxId); // server UUIDconsole.log(sandbox.name); // "my-env"const result = await sandbox.run("python", { args: ["main.py"] });console.log(result.stdout);await sandbox.update({ name: "new-name" });await sandbox.terminate();
Authenticated requests can use either the sandbox ID or sandbox name. Unauthenticated proxy requests can also use sandbox names for exposed user ports when allow_unauthenticated_access is enabled. The management URL on port 9501 still requires authentication.
Use get to check a single sandbox’s status and configuration, or list to see all sandboxes in your namespace.
CLI
Python
TypeScript
HTTP
# List active sandboxestl sbx ls# Running sandboxes onlytl sbx ls --running# Include all sandboxes regardless of statetl sbx ls --all
from tensorlake.sandbox import Sandbox# Connect returns a Sandbox handle (not SandboxInfo)sandbox = Sandbox.connect("my-env")print(sandbox.status) # property — fetches fresh from serverprint(sandbox.name)print(sandbox.sandbox_id)# Get the full metadata (image, resources, timeouts, etc.)info = sandbox.info()print(info.image)print(f"{info.resources.cpus} CPUs, {info.resources.memory_mb} MB RAM")# List all sandboxes in the namespacefor sb in Sandbox.list(): print(f"{sb.sandbox_id}: {sb.status}")
import { Sandbox } from "tensorlake";// Connect returns a Sandbox handle (not SandboxInfo)const sandbox = await Sandbox.connect("my-env");console.log(await sandbox.status()); // status is an async method in TSconsole.log(sandbox.name); // name is a getterconsole.log(sandbox.sandboxId);// Get the full metadata (image, resources, timeouts, etc.)const info = await sandbox.info();console.log(info.image, info.resources.cpus, info.resources.memoryMb);// List all sandboxes in the namespaceconst sandboxes = await Sandbox.list();for (const sb of sandboxes) { console.log(`${sb.sandboxId}: ${sb.status}`);}
# Get one sandbox (by name or ID)curl https://api.tensorlake.ai/sandboxes/my-env \ -H "Authorization: Bearer $TL_API_KEY"# List all sandboxescurl https://api.tensorlake.ai/sandboxes \ -H "Authorization: Bearer $TL_API_KEY"
Suspend a running named sandbox to pause it in place, then resume the same sandbox later exactly where it left off. Suspend and resume do not create a reusable artifact — for that, use Snapshots. Ephemeral sandboxes cannot be suspended — suspend calls on them return an error.
CLI
Python
TypeScript
HTTP
# Suspend a named sandbox (by name or ID)tl sbx suspend my-env# Resume it latertl sbx resume my-env
sandbox.suspend()sandbox.resume()
await sandbox.suspend();await sandbox.resume();
curl -X POST https://api.tensorlake.ai/sandboxes/my-env/suspend \ -H "Authorization: Bearer $TL_API_KEY"curl -X POST https://api.tensorlake.ai/sandboxes/my-env/resume \ -H "Authorization: Bearer $TL_API_KEY"
Terminate a sandbox when the work is done. Terminated is a final state and cannot be reversed. Sandboxes with timeout_secs set also terminate automatically once the timeout elapses.
If you want a single example that creates a sandbox, inspects it, lists sandboxes, and cleans up when finished, use one of the sessions below.
CLI
Python
TypeScript
HTTP
# Create an ephemeral sandbox (no name — cannot be suspended)tl sbx create --cpus 1.0 --memory 1024 --timeout 300# Create a named sandbox (can be suspended and resumed)tl sbx create my-env --cpus 1.0 --memory 1024 --timeout 300# Check status or list sandboxestl sbx lstl sbx ls --all# Terminate the sandbox when you are done (by name or ID)tl sbx terminate my-env
from tensorlake.sandbox import Sandbox# Ephemeral sandbox — no name, cannot be suspendedephemeral = Sandbox.create( cpus=1.0, memory_mb=1024, disk_mb=10240, timeout_secs=300,)# Named sandbox — can be suspended and resumednamed = Sandbox.create( name="my-env", cpus=1.0, memory_mb=1024, disk_mb=10240, timeout_secs=300,)print(f"Sandbox ID: {named.sandbox_id}")print(f"Status: {named.status}")# Get the full metadata (image, resources, timeouts, etc.)info = sandbox.info()print(f"Image: {info.image}")print(f"Resources: {info.resources.cpus} CPUs, {info.resources.memory_mb} MB RAM")sandboxes = Sandbox.list()for sb in sandboxes: print(f"{sb.sandbox_id}: {sb.status}")sandbox.terminate()print("Sandboxes terminated")
import { Sandbox } from "tensorlake";const ephemeral = await Sandbox.create({ cpus: 1.0, memoryMb: 1024, diskMb: 10240, timeoutSecs: 300,});const named = await Sandbox.create({ name: "my-env", cpus: 1.0, memoryMb: 1024, diskMb: 10240, timeoutSecs: 300,});console.log(named.sandboxId, named.status);# Get the full metadata (image, resources, timeouts, etc.)const info = await sandbox.info();console.log(info.image, info.resources.cpus, info.resources.memoryMb);const sandboxes = await Sandbox.list();for (const sandbox of sandboxes) { console.log(`${sandbox.sandboxId}: ${sandbox.status}`);}await sandbox.terminate();
# Create an ephemeral sandboxcurl -X POST https://api.tensorlake.ai/sandboxes \ -H "Authorization: Bearer $TL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "resources": {"cpus": 1.0, "memory_mb": 1024}, "timeout_secs": 300 }'# Create a named sandbox (supports suspend/resume)curl -X POST https://api.tensorlake.ai/sandboxes \ -H "Authorization: Bearer $TL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "my-env", "resources": {"cpus": 1.0, "memory_mb": 1024}, "timeout_secs": 300 }'# Get one sandboxcurl https://api.tensorlake.ai/sandboxes/<sandbox-id> \ -H "Authorization: Bearer $TL_API_KEY"# List all sandboxescurl https://api.tensorlake.ai/sandboxes \ -H "Authorization: Bearer $TL_API_KEY"# Deletecurl -X DELETE https://api.tensorlake.ai/sandboxes/<sandbox-id> \ -H "Authorization: Bearer $TL_API_KEY"
The Sandbox object returned by Sandbox.create() and Sandbox.connect() exposes the following properties. Both are resolved from the server on first access and cached for the lifetime of the object.
Property (Python)
Property (TypeScript)
Type
Description
sandbox_id
sandboxId
str
Server-assigned UUID. Always a UUID, never a name, even if you connected using a name.
name
name
str | None
Human-readable name, or None for ephemeral sandboxes.