Sandboxes
Daytona provides full composable computers — sandboxes — for AI agents.
Sandboxes are isolated runtime environments you can manage programmatically to run code. Each sandbox runs in isolation, giving it a dedicated kernel, filesystem, network stack, and allocated vCPU, RAM, and disk. Agents and developers get access to a full composable computer where they can install packages, run servers, compile code, and manage processes.
Sandboxes have 1 vCPU, 1GB RAM, and 3GiB disk by default. Organizations get a maximum sandbox resource limit of 4 vCPUs, 8GB RAM, and 10GB disk.
Sandboxes can use snapshots to capture a fully configured environment (base operating system, installed packages, dependencies and configuration) to create new sandboxes.
Default Linux container runtime.
LinuxLinux OS runtime in a virtual machine for running Linux-specific tools and workflows.
WindowsWindows OS runtime in a virtual machine for running Windows applications and tooling.
GPUNVIDIA GPU runtime for model inference, fine-tuning, and CUDA-accelerated compute.
Create Sandboxes
Section titled “Create Sandboxes”Daytona provides methods to create sandboxes.
- Navigate to Daytona Sandboxes ↗
- Click Create Sandbox
- Click Create
from daytona import Daytona
daytona = Daytona()sandbox = daytona.create()import { Daytona } from '@daytona/sdk'
const daytona = new Daytona()const sandbox = await daytona.create()require 'daytona'
daytona = Daytona::Daytona.newsandbox = daytona.createpackage main
import ( "context" "github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona")
func main() { client, _ := daytona.NewClient() ctx := context.Background() _, _ = client.Create(ctx, nil)}import io.daytona.sdk.Daytona;import io.daytona.sdk.Sandbox;
public class App { public static void main(String[] args) { try (Daytona daytona = new Daytona()) { Sandbox sandbox = daytona.create(); } }}daytona create [flags]curl 'https://app.daytona.io/api/sandbox' \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --data '{}'Snapshots
Section titled “Snapshots”Daytona provides pre-built snapshots for creating sandboxes.
-
Navigate to Daytona Sandboxes ↗
-
Click Create Sandbox
-
Select a snapshot
daytona-smalldaytona-mediumdaytona-large
-
Click Create
from daytona import Daytona, CreateSandboxFromSnapshotParams
daytona = Daytona()sandbox = daytona.create( CreateSandboxFromSnapshotParams( snapshot="daytona-medium", ))import { Daytona } from '@daytona/sdk'
const daytona = new Daytona()const sandbox = await daytona.create({ snapshot: 'daytona-medium',})require 'daytona'
daytona = Daytona::Daytona.newsandbox = daytona.create( Daytona::CreateSandboxFromSnapshotParams.new( snapshot: 'daytona-medium' ))package main
import ( "context" "github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona" "github.com/daytonaio/daytona/libs/sdk-go/pkg/types")
func main() { client, _ := daytona.NewClient() ctx := context.Background() params := types.SnapshotParams{ Snapshot: "daytona-medium", } _, _ = client.Create(ctx, params)}import io.daytona.sdk.Daytona;import io.daytona.sdk.Sandbox;import io.daytona.sdk.model.CreateSandboxFromSnapshotParams;
public class App { public static void main(String[] args) { try (Daytona daytona = new Daytona()) { CreateSandboxFromSnapshotParams params = new CreateSandboxFromSnapshotParams(); params.setSnapshot("daytona-medium"); Sandbox sandbox = daytona.create(params); } }}daytona create --snapshot daytona-mediumcurl 'https://app.daytona.io/api/sandbox' \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --data '{ "snapshot": "daytona-medium"}'Custom Resources
Section titled “Custom Resources”Daytona provides methods to create sandboxes with custom resources.
- Navigate to Daytona Sandboxes ↗
- Click Create Sandbox
- Enter a base
image - Set Resources (
cpu,memory,disk) to the values within your organization’s limits - Click Create
from daytona import Daytona, CreateSandboxFromImageParams, Image, Resources
daytona = Daytona()sandbox = daytona.create( CreateSandboxFromImageParams( image=Image.debian_slim("3.12"), resources=Resources(cpu=2, memory=4, disk=8), ))import { Daytona, Image } from '@daytona/sdk'
const daytona = new Daytona()const sandbox = await daytona.create({ image: Image.debianSlim('3.12'), resources: { cpu: 2, memory: 4, disk: 8 },})require 'daytona'
daytona = Daytona::Daytona.newsandbox = daytona.create( Daytona::CreateSandboxFromImageParams.new( image: Daytona::Image.debian_slim('3.12'), resources: Daytona::Resources.new( cpu: 2, memory: 4, disk: 8 ) ))package main
import ( "context" "github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona" "github.com/daytonaio/daytona/libs/sdk-go/pkg/types")
func main() { client, _ := daytona.NewClient() ctx := context.Background() _, _ = client.Create(ctx, types.ImageParams{ Image: "python:3.12", Resources: &types.Resources{ CPU: 2, Memory: 4, Disk: 8, }, })}import io.daytona.sdk.Daytona;import io.daytona.sdk.Sandbox;import io.daytona.sdk.model.CreateSandboxFromImageParams;import io.daytona.sdk.model.Resources;
final class CreateSandboxResources { public static void main(String[] args) { try (Daytona daytona = new Daytona()) { CreateSandboxFromImageParams params = new CreateSandboxFromImageParams(); params.setImage("python:3.12"); Resources resources = new Resources(); resources.setCpu(2); resources.setMemory(4); resources.setDisk(8); params.setResources(resources); Sandbox sandbox = daytona.create(params); } }}daytona create --cpu 2 --memory 4 --disk 8curl 'https://app.daytona.io/api/sandbox' \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --data '{ "image": "python:3.12", "cpu": 2, "memory": 4, "disk": 8}'Ephemeral Sandboxes
Section titled “Ephemeral Sandboxes”Daytona provides methods to create ephemeral sandboxes.
Ephemeral sandboxes are automatically deleted once they are stopped.
- Navigate to Daytona Sandboxes ↗
- Click Create Sandbox
- Set Ephemeral to
Trueor set the auto-delete interval to0 - Click Create
from daytona import Daytona, CreateSandboxFromSnapshotParams
daytona = Daytona()params = CreateSandboxFromSnapshotParams( ephemeral=True, auto_stop_interval=5,)sandbox = daytona.create(params)import { Daytona } from '@daytona/sdk'
const daytona = new Daytona()const sandbox = await daytona.create({ ephemeral: true, autoStopInterval: 5,})require 'daytona'
daytona = Daytona::Daytona.newparams = Daytona::CreateSandboxFromSnapshotParams.new( ephemeral: true, auto_stop_interval: 5)sandbox = daytona.create(params)package main
import ( "context" "github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona" "github.com/daytonaio/daytona/libs/sdk-go/pkg/types")
func main() { client, _ := daytona.NewClient() ctx := context.Background()
autoStopInterval := 5 params := types.SnapshotParams{ SandboxBaseParams: types.SandboxBaseParams{ Language: types.CodeLanguagePython, Ephemeral: true, AutoStopInterval: &autoStopInterval, }, } _, _ = client.Create(ctx, params)}import io.daytona.sdk.Daytona;import io.daytona.sdk.Sandbox;import io.daytona.sdk.model.CreateSandboxFromSnapshotParams;
public class App { public static void main(String[] args) { try (Daytona daytona = new Daytona()) { CreateSandboxFromSnapshotParams params = new CreateSandboxFromSnapshotParams(); params.setAutoDeleteInterval(0); params.setAutoStopInterval(5); Sandbox sandbox = daytona.create(params); } }}daytona create --auto-delete 0 --auto-stop 5curl 'https://app.daytona.io/api/sandbox' \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --data '{ "autoDeleteInterval": 0, "autoStopInterval": 5}'Linked Sandboxes
Section titled “Linked Sandboxes”Daytona provides methods to create linked sandboxes.
Linked sandboxes are attached to an existing parent sandbox at creation time.
-
Lifecycle
Linked sandboxes are always ephemeral and cannot be persisted or resumed after stop. The auto-delete interval must be exactly
0on create; this is enforced, not a default. The auto-stop interval sets the idle period in minutes after which the child sandbox stops. Once stopped, linked children are auto-deleted. Deleting the parent deletes all of its linked children (cascade). One parent may have many linked children (1:N). -
Networking
Linked sandboxes share an internal link network. Connections work in both directions: the parent can reach each child and each child can reach the parent. Every sandbox on the link network is registered under its sandbox name and ID as DNS aliases, so either works as the host. For example:
telnet LINKED_SANDBOX_ID 5555from the parent reaches port5555on the linked child sandbox.
- Create a parent sandbox
- Create one or more child sandboxes that reference the parent’s sandbox ID. This records the relationship on the child sandbox as the linked sandbox ID. Omitting the linked sandbox parameter yields an unlinked sandbox.
from daytona import CreateSandboxFromSnapshotParams, Daytona
daytona = Daytona()
parent = daytona.create()
child = daytona.create( CreateSandboxFromSnapshotParams( linked_sandbox=parent.id, ephemeral=True, ))
# The link network registers each sandbox under its name as a DNS aliasresponse = child.process.exec(f"curl http://{parent.name}:3000/")import { Daytona } from '@daytona/sdk'
const daytona = new Daytona()
const parent = await daytona.create()
const child = await daytona.create({ linkedSandbox: parent.id, ephemeral: true,})
// The link network registers each sandbox under its name as a DNS aliasconst response = await child.process.executeCommand( `curl http://${parent.name}:3000/`)require 'daytona'
daytona = Daytona::Daytona.new
parent = daytona.create
child = daytona.create( Daytona::CreateSandboxFromSnapshotParams.new( linked_sandbox: parent.id, ephemeral: true ))
# The link network registers each sandbox under its name and ID as DNS aliases.# The Ruby SDK does not expose the sandbox name, so address the parent by ID.response = child.process.exec(command: "curl http://#{parent.id}:3000/")package main
import ( "context" "fmt"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona" "github.com/daytonaio/daytona/libs/sdk-go/pkg/types")
func main() { client, _ := daytona.NewClient() ctx := context.Background()
parent, _ := client.Create(ctx, types.SnapshotParams{})
child, _ := client.Create(ctx, types.SnapshotParams{ SandboxBaseParams: types.SandboxBaseParams{ LinkedSandbox: parent.ID, Ephemeral: true, }, })
// The link network registers each sandbox under its name as a DNS alias response, _ := child.Process.ExecuteCommand(ctx, fmt.Sprintf("curl http://%s:3000/", parent.Name)) fmt.Println(response.Result)}import io.daytona.sdk.Daytona;import io.daytona.sdk.Sandbox;import io.daytona.sdk.model.CreateSandboxFromSnapshotParams;import io.daytona.sdk.model.ExecuteResponse;
public class App { public static void main(String[] args) { try (Daytona daytona = new Daytona()) { Sandbox parent = daytona.create();
CreateSandboxFromSnapshotParams childParams = new CreateSandboxFromSnapshotParams(); childParams.setLinkedSandbox(parent.getId()); childParams.setAutoDeleteInterval(0); // linked sandboxes must be ephemeral Sandbox child = daytona.create(childParams);
// The link network registers each sandbox under its name as a DNS alias ExecuteResponse response = child.getProcess() .executeCommand("curl http://" + parent.getName() + ":3000/"); } }}# Create parent sandboxcurl 'https://app.daytona.io/api/sandbox' \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --data '{}'
# Create linked child sandbox (replace PARENT_SANDBOX_ID with the id from the first response)curl 'https://app.daytona.io/api/sandbox' \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --data '{ "linkedSandbox": "PARENT_SANDBOX_ID", "autoDeleteInterval": 0}'Resources
Section titled “Resources”Sandboxes have 1 vCPU, 1GB RAM, and 3GiB disk by default. Organizations get a maximum sandbox resource limit of 4 vCPUs, 8GB RAM, and 10GB disk.
| Resource | Unit | Default | Minimum | Maximum |
|---|---|---|---|---|
| CPU | vCPU | 1 | 1 | 4 |
| Memory | GiB | 1 | 1 | 8 |
| Disk | GiB | 3 | 1 | 10 |
Start Sandboxes
Section titled “Start Sandboxes”Daytona provides methods to start sandboxes.
- Navigate to Daytona Sandboxes ↗
- Click the start icon (▶) next to the sandbox you want to start
sandbox.start()await sandbox.start()sandbox.startsandbox.Start(ctx)sandbox.start();daytona start [SANDBOX_ID] | [SANDBOX_NAME] [flags]curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/start' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY'Get Sandbox
Section titled “Get Sandbox”Daytona provides methods to get a sandbox by ID or name.
sandbox = daytona.get("my-sandbox-id-or-name")const sandbox = await daytona.get('my-sandbox-id-or-name')sandbox = daytona.get('my-sandbox-id-or-name')sandbox, err := client.Get(ctx, "my-sandbox-id-or-name")Sandbox sandbox = daytona.get("my-sandbox-id-or-name");daytona info [SANDBOX_ID] | [SANDBOX_NAME] [flags]curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}' \ --header 'Authorization: Bearer YOUR_API_KEY'List Sandboxes
Section titled “List Sandboxes”Daytona provides methods to list sandboxes.
for sandbox in daytona.list(): print(sandbox.id)for await (const sandbox of daytona.list()) { console.log(sandbox.id)}daytona.list.each { |sandbox| puts sandbox.id }iter := client.List(ctx, nil)defer iter.Close()for iter.Next() { sandbox := iter.Value() fmt.Println(sandbox.ID)}if err := iter.Err(); err != nil { log.Fatal(err)}Iterator<Map<String, Object>> iter = daytona.list();while (iter.hasNext()) { Map<String, Object> sandbox = iter.next(); System.out.println(sandbox.get("id"));}daytona list [flags]curl 'https://app.daytona.io/api/sandbox' \ --header 'Authorization: Bearer YOUR_API_KEY'Stop Sandboxes
Section titled “Stop Sandboxes”Daytona provides methods to stop sandboxes.
Stopped sandboxes maintain filesystem persistence while their memory state is cleared. They incur only disk usage costs and can be started again when needed.
The stopped state should be used when a sandbox is expected to be started again. Otherwise, it is recommended to stop and then archive the sandbox to eliminate disk usage costs.
- Navigate to Daytona Sandboxes ↗
- Click the stop icon (⏹) next to the sandbox you want to stop
sandbox.stop()await sandbox.stop()sandbox.stopsandbox.Stop(ctx)sandbox.stop();daytona stop [SANDBOX_ID] | [SANDBOX_NAME] [flags]curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/stop' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY'If you need a faster shutdown, use force stop (force=true / --force) to terminate the sandbox immediately. Force stop is ungraceful and should be used when quick termination is more important than process cleanup. Avoid force stop for normal shutdowns where the process should flush buffers, write final state, or run cleanup hooks.
Common use cases for force stop include:
- you need to reduce stop time and can accept immediate termination
- the entrypoint ignores termination signals or hangs during shutdown
Archive Sandboxes
Section titled “Archive Sandboxes”Daytona provides methods to archive sandboxes.
- Ensure the sandbox is stopped
- Archive the sandbox
- Wait for the sandbox to reach the archived state to move filesystem state to object storage
- Start the sandbox again when you need to use it
sandbox.archive()await sandbox.archive()sandbox.archivesandbox.Archive(ctx)daytona archive [SANDBOX_ID] | [SANDBOX_NAME] [flags]curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/archive' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY'Recover Sandboxes
Section titled “Recover Sandboxes”Daytona provides methods to recover sandboxes.
- Ensure the sandbox is in error state
- Check that the sandbox is recoverable
- Resolve any underlying issue that requires user intervention
- Recover the sandbox and wait for it to be ready
# Check if the sandbox is recoverableif sandbox.recoverable: sandbox.recover()sandbox.recover()// Check if the sandbox is recoverableif (sandbox.recoverable) { await sandbox.recover()}await sandbox.recover()# Check if the sandbox is in an error state before recoveringif sandbox.state == 'error' sandbox.recoverendsandbox.recovercurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/recover' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY'curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/recover' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY'Resize Sandboxes
Section titled “Resize Sandboxes”Daytona provides methods to resize sandbox resources after creation.
On a running sandbox, you can increase CPU and memory without interruption. To decrease CPU or memory, or to increase disk capacity, stop the sandbox first. Disk size can only be increased and cannot be decreased.
Resizing updates the sandbox resource allocation (cpu, memory, and disk) for that sandbox only. CPU and memory control compute capacity for running workloads, while disk controls persistent filesystem capacity. Values must be integers and stay within your organization’s per-sandbox resource limits.
- Choose the new CPU, memory, and disk values within your organization’s limits
- Ensure the sandbox is stopped if you need to decrease CPU or memory, or increase disk
- Resize the sandbox with the new resource values
- Start the sandbox
# Resize a started sandbox (CPU and memory can be increased)sandbox.resize(Resources(cpu=2, memory=4))
# Resize a stopped sandbox (CPU and memory can change, disk can only increase)sandbox.stop()sandbox.resize(Resources(cpu=4, memory=8, disk=20))sandbox.start()// Resize a started sandbox (CPU and memory can be increased)await sandbox.resize({ cpu: 2, memory: 4 })
// Resize a stopped sandbox (CPU and memory can change, disk can only increase)await sandbox.stop()await sandbox.resize({ cpu: 4, memory: 8, disk: 20 })await sandbox.start()# Resize a started sandbox (CPU and memory can be increased)sandbox.resize(Daytona::Resources.new(cpu: 2, memory: 4))
# Resize a stopped sandbox (CPU and memory can change, disk can only increase)sandbox.stopsandbox.resize(Daytona::Resources.new(cpu: 4, memory: 8, disk: 20))sandbox.start// Resize a started sandbox (CPU and memory can be increased)err := sandbox.Resize(ctx, &types.Resources{CPU: 2, Memory: 4})
// Resize a stopped sandbox (CPU and memory can change, disk can only increase)err = sandbox.Stop(ctx)err = sandbox.Resize(ctx, &types.Resources{CPU: 4, Memory: 8, Disk: 20})err = sandbox.Start(ctx)curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/resize' \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --data '{ "cpu": 2, "memory": 4, "disk": 20}'To verify CPU and memory limits inside the sandbox after resizing, read cgroup values directly. Tools such as nproc, free, top, htop, /proc/cpuinfo, and /proc/meminfo read host-level values and do not reflect sandbox resource limits.
cat /sys/fs/cgroup/cpu.max # "<quota> <period>" (cores = quota / period)cat /sys/fs/cgroup/memory.max # bytesdf -h / # diskFork Sandboxes
Section titled “Fork Sandboxes”Daytona provides methods to fork sandboxes.
Forking creates a duplicate of your sandbox’s filesystem and memory, and copies it into a new sandbox. The new sandbox is fully independent: it can be started, stopped, and deleted without affecting the original. The sandbox must be in started state before forking.
Daytona tracks the parent-child relationship in a fork tree, so you can always trace a fork’s lineage back to the sandbox it was created from. You can fork a fork, building out branches as needed. The parent sandbox cannot be deleted while it has active fork children.
- Navigate to Daytona Sandboxes ↗
- Click the three-dot menu (⋮) next to the sandbox you want to fork
- Select Fork
# Fork sandbox through the Sandbox instanceforked = sandbox._experimental_fork(name="my-forked-sandbox")// Fork sandbox through the Sandbox instanceconst forkedSandbox = await sandbox._experimental_fork({ name: "my-forked-sandbox" });
// Or use the Daytona helper methodconst forkedSandbox = await daytona._experimental_fork(sandbox, { name: "my-forked-sandbox" });# Fork sandbox through the Sandbox instanceforkedSandbox = sandbox.experimental_fork(name: "my-forked-sandbox")// Fork sandbox through the Sandbox instancename := "my-forked-sandbox"forkedSandbox, err := sandbox.ExperimentalFork(ctx, &name)if err != nil { return err}// Fork sandbox through the Sandbox instanceSandbox forkedSandbox = sandbox.experimentalFork("my-forked-sandbox", 60);curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/fork' \ --request POST \ --header 'X-Daytona-Organization-ID: YOUR_ORGANIZATION_ID' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --data '{ "name": "my-forked-sandbox"}'Label Sandboxes
Section titled “Label Sandboxes”Daytona provides methods to set sandbox labels.
- Navigate to Daytona Sandboxes ↗
- Click Create Sandbox
- Click Add Labels
- Enter the labels in key-value pairs
sandbox.set_labels({ "team": "platform", "env": "staging",})await sandbox.setLabels({ team: 'platform', env: 'staging',})sandbox.labels = { team: 'platform', env: 'staging'}err := sandbox.SetLabels(ctx, map[string]string{ "team": "platform", "env": "staging",})Map<String, String> labels = new HashMap<>();labels.put("team", "platform");labels.put("env", "staging");sandbox.setLabels(labels);curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/labels' \ --request PUT \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --data '{ "labels": { "team": "platform", "env": "staging" }}'Create Snapshot from Sandbox
Section titled “Create Snapshot from Sandbox”Daytona provides methods to create a snapshot from an existing sandbox.
A snapshot captures a point-in-time copy of a sandbox that you can use as a base to create new sandboxes, templating a known-good environment for reuse.
Container sandboxes capture filesystem state only. For hot and cold snapshots on VM sandboxes (Linux and Windows), see VM sandboxes.
sandbox._experimental_create_snapshot("my-sandbox-snapshot")await sandbox._experimental_createSnapshot('my-sandbox-snapshot')sandbox.experimental_create_snapshot(name: "my-sandbox-snapshot")err := sandbox.ExperimentalCreateSnapshot(ctx, "my-sandbox-snapshot")if err != nil { return err}sandbox.experimentalCreateSnapshot("my-sandbox-snapshot");curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/snapshot' \ --request POST \ --header 'X-Daytona-Organization-ID: YOUR_ORGANIZATION_ID' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --data '{ "name": "my-sandbox-snapshot"}'Delete Sandboxes
Section titled “Delete Sandboxes”Daytona provides methods to delete sandboxes.
- Navigate to Daytona Sandboxes ↗
- Click the Delete button next to the sandbox you want to delete.
sandbox.delete()await sandbox.delete()sandbox.deleteerr = sandbox.Delete(ctx)sandbox.delete();daytona delete [SANDBOX_ID] | [SANDBOX_NAME] [flags]curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}' \ --request DELETE \ --header 'Authorization: Bearer YOUR_API_KEY'Sandbox lifecycle
Section titled “Sandbox lifecycle”A sandbox can have several different states. Each state reflects the status of your sandbox.
| State | Description |
|---|---|
| Creating | The sandbox is provisioning and will be ready to use. |
| Pulling Snapshot | The sandbox is pulling a snapshot to provide a base environment. |
| Building Snapshot | The sandbox is building a snapshot to provide a base environment. |
| Pending Build | The sandbox build is pending and will start shortly. |
| Build Failed | The sandbox build failed and needs to be retried. |
| Starting | The sandbox is starting and will be ready to use. |
| Started | The sandbox has started and is ready to use. |
| Stopping | The sandbox is stopping and will no longer accept requests. |
| Stopped | The sandbox has stopped and is no longer running. |
| Pausing | The sandbox is pausing while its filesystem and memory state are preserved. |
| Paused | The sandbox is paused with its filesystem and memory state preserved. |
| Resuming | The sandbox is resuming from a paused state and will be ready to use. |
| Archiving | The sandbox is archiving and its state will be preserved. |
| Archived | The sandbox has been archived and its state is preserved. |
| Restoring | The sandbox is being restored from archive and will be ready to use shortly. |
| Resizing | The sandbox is being resized to a new set of resources. |
| Snapshotting | The sandbox is creating a snapshot of its filesystem and memory. |
| Forking | The sandbox is being forked into a new independent sandbox. |
| Deleting | The sandbox is deleting and will be removed. |
| Deleted | The sandbox has been deleted and no longer exists. |
| Error | The sandbox is in an error state and needs to be recovered. |
| Unknown | The default sandbox state before it is created. |
The diagram demonstrates the states and possible transitions between them.
State transitions
Section titled “State transitions”A sandbox can transition between states in response to various actions. The following table lists the initial state, target state, and trigger for the transition.
| Initial state | Target state | Trigger |
|---|---|---|
| Unknown | Pulling Snapshot | The base snapshot is being pulled to provide the sandbox environment. |
| Unknown | Building Snapshot | The sandbox uses a declarative image build, which begins building. |
| Pending Build | Building Snapshot | The queued image build starts. |
| Building Snapshot | Build Failed | The image build fails or times out. |
| Pulling Snapshot | Creating | The snapshot is available and the sandbox container is created. |
| Building Snapshot | Creating | The snapshot finishes building and the sandbox container is created. |
| Creating | Started | The sandbox container finishes initializing and is running. |
| Stopped | Starting | A start is requested and the sandbox boots. |
| Stopped | Restoring | A start is requested and the sandbox is restored from a backup. |
| Archived | Restoring | A start is requested and the archived filesystem is restored from object storage. |
| Restoring | Started | The restore completes and the sandbox is running. |
| Starting | Started | The sandbox is running and ready to accept requests. |
| Started | Stopping | A stop is requested, or the auto-stop interval is exceeded. |
| Stopping | Stopped | The sandbox process exits and its memory state is cleared. |
| Started | Pausing | A pause is requested. |
| Pausing | Paused | The filesystem and memory state are preserved. |
| Paused | Resuming | A start is requested on a paused sandbox. |
| Paused | Stopping | A stop is requested on a paused sandbox. |
| Resuming | Started | The sandbox resumes from memory and is running. |
| Stopped | Archiving | An archive is requested, or the auto-archive interval is exceeded. |
| Archiving | Archived | The backup completes and the filesystem is moved to object storage. |
| Started | Resizing | CPU or memory is increased on a running sandbox. |
| Stopped | Resizing | Resources are changed on a stopped sandbox. |
| Resizing | Started | The running sandbox returns to service after resizing. |
| Resizing | Stopped | The stopped sandbox completes resizing. |
| Started | Snapshotting | A snapshot of the filesystem and memory is created. |
| Stopped | Snapshotting | A snapshot of the filesystem is created. |
| Snapshotting | Started | The snapshot completes and the sandbox returns to service. |
| Snapshotting | Stopped | The snapshot completes and the sandbox remains stopped. |
| Started | Forking | The sandbox is forked into a new independent sandbox. |
| Forking | Started | The fork completes and the sandbox returns to service. |
| Started | Deleting | A delete is requested, or the auto-delete interval is exceeded. |
| Stopped | Deleting | A delete is requested. |
| Archived | Deleted | An archived sandbox is deleted directly without being restored. |
| Deleting | Deleted | The sandbox is removed and its resources are released. |
| Started | Error | An operation fails or times out. |
| Error | Restoring | A recover is requested for a recoverable error and the sandbox is restored. |
| Error | Archiving | An errored sandbox with a completed backup is archived to preserve its state. |
Multiple runtime support
Section titled “Multiple runtime support”Daytona sandboxes support Python, TypeScript, and JavaScript programming language runtimes for direct code execution inside the sandbox. The language parameter controls which programming language runtime is used for the sandbox:
pythontypescriptjavascript
If omitted, the Daytona SDK will default to python. To override this, explicitly set the language value when creating the sandbox.
Automated lifecycle management
Section titled “Automated lifecycle management”Sandboxes can be automatically stopped, archived, and deleted based on user-defined intervals. The intervals act as a TTL (time-to-live) mechanism for the sandbox. You can also refresh the last activity timestamp to explicitly signal activity when lifecycle behavior depends on inactivity intervals.
Update sandbox last activity
Section titled “Update sandbox last activity”Daytona provides methods to update a sandbox’s last activity timestamp.
This updates the sandbox’s recorded activity time without changing its runtime state. It is useful when your workflow is driven by external systems or background orchestration that may not reset inactivity tracking.
sandbox.refresh_activity()await sandbox.refreshActivity()sandbox.refresh_activitycurl 'https://app.daytona.io/api/sandbox/{sandboxId}/last-activity' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY'Auto-stop interval
Section titled “Auto-stop interval”The auto-stop interval sets the amount of time after which a running sandbox is automatically stopped. The auto-stop triggers even if there are internal processes running in the sandbox.
- Navigate to Daytona Sandboxes ↗
- Click Create Sandbox
- Set
auto-stopinterval to the desired value in minutes0: disables the auto-stop functionality, allowing the sandbox to run indefinitely- if not set, the default interval of 15 minutes is used
- Click Create
sandbox = daytona.create(CreateSandboxFromSnapshotParams( snapshot="my-snapshot-name", # Disables the auto-stop feature - default is 15 minutes auto_stop_interval=0,))const sandbox = await daytona.create({ snapshot: 'my-snapshot-name', // Disables the auto-stop feature - default is 15 minutes autoStopInterval: 0,})sandbox = daytona.create( Daytona::CreateSandboxFromSnapshotParams.new( snapshot: 'my-snapshot-name', # Disables the auto-stop feature - default is 15 minutes auto_stop_interval: 0 ))// Create a sandbox with auto-stop disabledautoStopInterval := 0params := types.SnapshotParams{ Snapshot: "my-snapshot-name", SandboxBaseParams: types.SandboxBaseParams{ AutoStopInterval: &autoStopInterval, },}sandbox, err := client.Create(ctx, params)import io.daytona.sdk.Daytona;import io.daytona.sdk.Sandbox;import io.daytona.sdk.model.CreateSandboxFromSnapshotParams;
public class App { public static void main(String[] args) { try (Daytona daytona = new Daytona()) { CreateSandboxFromSnapshotParams params = new CreateSandboxFromSnapshotParams(); params.setSnapshot("my-snapshot-name"); // Disables the auto-stop feature - default is 15 minutes params.setAutoStopInterval(0); Sandbox sandbox = daytona.create(params); } }}curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/autostop/{interval}' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY'The system differentiates between “internal processes” and “active user interaction”. Merely having a script or background task running is not sufficient to keep the sandbox alive.
What resets the timer
Section titled “What resets the timer”The inactivity timer resets only for specific external interactions:
- Updates to sandbox lifecycle states
- Network requests through sandbox previews
- Active SSH connections
- API requests to the Daytona Toolbox SDK
What does not reset the timer
Section titled “What does not reset the timer”The following do not reset the timer:
- SDK requests that are not toolbox actions
- Background scripts (e.g.,
npm run devrun as a fire-and-forget command) - Long-running tasks without external interaction
- Processes that don’t involve active monitoring
If you run a long-running task like LLM inference that takes more than 15 minutes to complete without any external interaction, the sandbox may auto-stop mid-process because the process itself doesn’t count as “activity”, therefore the timer is not reset.
Auto-archive interval
Section titled “Auto-archive interval”Daytona provides methods to set the auto-archive interval.
The auto-archive interval sets the amount of time after which a continuously stopped sandbox is automatically archived.
- Navigate to Daytona Sandboxes ↗
- Click Create Sandbox
- Set
auto-archiveinterval to the desired value in minutes0: the maximum interval of 30 days is used- if not set, the default interval of 7 days is used
- Click Create
sandbox = daytona.create(CreateSandboxFromSnapshotParams( snapshot="my-snapshot-name", # Auto-archive after a sandbox has been stopped for 1 hour auto_archive_interval=60,))const sandbox = await daytona.create({ snapshot: 'my-snapshot-name', // Auto-archive after a sandbox has been stopped for 1 hour autoArchiveInterval: 60,})sandbox = daytona.create( Daytona::CreateSandboxFromSnapshotParams.new( snapshot: 'my-snapshot-name', # Auto-archive after a sandbox has been stopped for 1 hour auto_archive_interval: 60 ))// Create a sandbox with auto-archive after 1 hourautoArchiveInterval := 60params := types.SnapshotParams{ Snapshot: "my-snapshot-name", SandboxBaseParams: types.SandboxBaseParams{ AutoArchiveInterval: &autoArchiveInterval, },}sandbox, err := client.Create(ctx, params)import io.daytona.sdk.Daytona;import io.daytona.sdk.Sandbox;import io.daytona.sdk.model.CreateSandboxFromSnapshotParams;
public class App { public static void main(String[] args) { try (Daytona daytona = new Daytona()) { CreateSandboxFromSnapshotParams params = new CreateSandboxFromSnapshotParams(); params.setSnapshot("my-snapshot-name"); // Auto-archive after a sandbox has been stopped for 1 hour params.setAutoArchiveInterval(60); Sandbox sandbox = daytona.create(params); } }}curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/autoarchive/{interval}' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY'Auto-delete interval
Section titled “Auto-delete interval”Daytona provides methods to set the auto-delete interval.
The auto-delete interval sets the amount of time after which a continuously stopped sandbox is automatically deleted.
- Navigate to Daytona Sandboxes ↗
- Click Create Sandbox
- Set
auto-deleteto the desired value in minutes-1: disables the auto-delete functionality0: the sandbox is deleted immediately after it is stopped- if not set, the sandbox is not deleted automatically
- Click Create
sandbox = daytona.create(CreateSandboxFromSnapshotParams( snapshot="my-snapshot-name", # Auto-delete after a sandbox has been stopped for 1 hour auto_delete_interval=60,))
# Delete the sandbox immediately after it has been stoppedsandbox.set_auto_delete_interval(0)
# Disable auto-deletionsandbox.set_auto_delete_interval(-1)const sandbox = await daytona.create({ snapshot: 'my-snapshot-name', // Auto-delete after a sandbox has been stopped for 1 hour autoDeleteInterval: 60,})
// Delete the sandbox immediately after it has been stoppedawait sandbox.setAutoDeleteInterval(0)
// Disable auto-deletionawait sandbox.setAutoDeleteInterval(-1)sandbox = daytona.create( Daytona::CreateSandboxFromSnapshotParams.new( snapshot: 'my-snapshot-name', # Auto-delete after a sandbox has been stopped for 1 hour auto_delete_interval: 60 ))
# Delete the sandbox immediately after it has been stoppedsandbox.auto_delete_interval = 0
# Disable auto-deletionsandbox.auto_delete_interval = -1// Create a sandbox with auto-delete after 1 hourautoDeleteInterval := 60params := types.SnapshotParams{ Snapshot: "my-snapshot-name", SandboxBaseParams: types.SandboxBaseParams{ AutoDeleteInterval: &autoDeleteInterval, },}sandbox, err := client.Create(ctx, params)
// Delete the sandbox immediately after it has been stoppedzeroInterval := 0err = sandbox.SetAutoDeleteInterval(ctx, &zeroInterval)
// Disable auto-deletiondisableInterval := -1err = sandbox.SetAutoDeleteInterval(ctx, &disableInterval)import io.daytona.sdk.Daytona;import io.daytona.sdk.Sandbox;import io.daytona.sdk.model.CreateSandboxFromSnapshotParams;
public class App { public static void main(String[] args) { try (Daytona daytona = new Daytona()) { CreateSandboxFromSnapshotParams params = new CreateSandboxFromSnapshotParams(); params.setSnapshot("my-snapshot-name"); // Auto-delete after a sandbox has been stopped for 1 hour params.setAutoDeleteInterval(60); Sandbox sandbox = daytona.create(params);
// Delete the sandbox immediately after it has been stopped sandbox.setAutoDeleteInterval(0);
// Disable auto-deletion sandbox.setAutoDeleteInterval(-1); } }}curl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/autodelete/{interval}' \ --request POST \ --header 'Authorization: Bearer YOUR_API_KEY'Running indefinitely
Section titled “Running indefinitely”Daytona provides methods to run sandboxes indefinitely.
By default, Daytona sandboxes auto-stop after 15 minutes of inactivity. To keep a sandbox running without interruption, set the auto-stop interval to 0 when creating a new sandbox.
- Navigate to Daytona Sandboxes ↗
- Click Create Sandbox
- Set
auto-stopto0 - Click Create
sandbox = daytona.create(CreateSandboxFromSnapshotParams( snapshot="my_awesome_snapshot", # Disables the auto-stop feature - default is 15 minutes auto_stop_interval=0,))const sandbox = await daytona.create({ snapshot: 'my_awesome_snapshot', // Disables the auto-stop feature - default is 15 minutes autoStopInterval: 0,})sandbox = daytona.create( Daytona::CreateSandboxFromSnapshotParams.new( snapshot: 'my_awesome_snapshot', # Disables the auto-stop feature - default is 15 minutes auto_stop_interval: 0 ))// Disables the auto-stop feature - default is 15 minutesautoStopInterval := 0params := types.SnapshotParams{ Snapshot: "my_awesome_snapshot", SandboxBaseParams: types.SandboxBaseParams{ AutoStopInterval: &autoStopInterval, },}sandbox, err := client.Create(ctx, params)import io.daytona.sdk.Daytona;import io.daytona.sdk.Sandbox;import io.daytona.sdk.model.CreateSandboxFromSnapshotParams;
public class App { public static void main(String[] args) { try (Daytona daytona = new Daytona()) { CreateSandboxFromSnapshotParams params = new CreateSandboxFromSnapshotParams(); params.setSnapshot("my_awesome_snapshot"); // Disables the auto-stop feature - default is 15 minutes params.setAutoStopInterval(0); Sandbox sandbox = daytona.create(params); } }}