Scale
Sandbox scalability and concurrency.
Daytona sandboxes are designed to be created and operated at high volume. A single sandbox scales up by bursting beyond its guaranteed resources, a fleet scales out by running many sandboxes at once, and each sandbox runs multiple processes concurrently.
Scale operates along three dimensions:
| Dimension | What scales | Mechanisms |
|---|---|---|
| Sandbox (vertical) | vCPU, RAM, and disk of a single sandbox | • Custom resources • Resource limits |
| Fleet (horizontal) | Number of sandboxes running simultaneously | • Snapshot fan-out |
| Workload (concurrency) | Concurrent processes in a sandbox | • Sessions • Background commands • PTY sessions |
Sandbox scaling
Sandbox scaling sets the resources of a single sandbox: vCPU, memory, and disk. The resource envelope is fixed when the sandbox is created; there is no resize operation.
The requested resources are a guaranteed floor, reserved at placement; beyond it the sandbox uses idle host capacity up to its resource limits, which default to the platform caps.
Size the guarantee for the workload's average, and let bursting absorb the peaks. For a fixed shape with no bursting, set every limit equal to its request.
Guarantee CPU, memory, and disk when creating a sandbox.
from daytona import Daytona
from daytona.v2 import Resources
daytona = Daytona()
# Guarantee 2 vCPUs, 4 GiB of RAM, and 16 GiB of disk for the sandbox
sandbox = daytona.v2.create(
resources=Resources(cpu=2, memory=4, disk=16),
)| Parameter | Type | Description |
|---|---|---|
cpu | float | Sets the CPU guarantee in cores. The value can be fractional. The API raises the CPU guarantee to at least 1 core per 4 GiB of memory. |
memory | int | In GiB. |
disk | int | In GiB. |
Fleet scaling
Fleet scaling raises how many sandboxes run at once. The unit of scale is the sandbox: instead of packing unrelated workloads into one environment, create one per user, task, or agent.
Each sandbox is a hardware-isolated microVM, so a fleet scales linearly: each sandbox adds capacity without contention, and a failure in one does not affect others. Creation is fast and asynchronous, so scale on demand: create when work arrives, delete when done.
Snapshot fan-out starts each unit of work from the memory and disk of one prepared snapshot, so any number of identical environments run from the same state. Snapshot fan-out works with Linux sandboxes. macOS sandboxes start from a disk image instead: see macOS snapshots.
from concurrent.futures import ThreadPoolExecutor
from daytona import Daytona
daytona = Daytona()
def run_task(shard: int) -> str:
# Each task gets its own isolated sandbox from the same snapshot
sandbox = daytona.v2.create_from_snapshot("my-snapshot")
response = sandbox.process.run(f"python3 run.py --shard {shard}")
# Delete the sandbox when the task is done
sandbox.delete()
return response.stdout
# Create and run 20 sandboxes concurrently from the same snapshot
with ThreadPoolExecutor(max_workers=20) as pool:
results = list(pool.map(run_task, range(20)))
print(results)| Parameter | Type | Description |
|---|---|---|
wait | int | Sets how many seconds create_from_snapshot waits for the sandbox to start. The default is 60. When wait runs out, create_from_snapshot returns the sandbox without raising. The returned sandbox may not have started. |
Workload concurrency
Workload concurrency runs multiple processes inside a single sandbox. A single sandbox can run an API server, a database, and background workers side by side: all processes share the sandbox's filesystem and network, and exposed ports are reachable through previews.
Every command runs as a process: run starts a process and waits for it, while start returns a handle immediately and the process continues in the background. Sessions are shared shells: commands in a session run sequentially and share state, so parallelism comes from separate sessions or background processes. Pseudo terminal (PTY) sessions add interactive terminals.
from daytona import Daytona
daytona = Daytona()
sandbox = daytona.v2.create()
# Start the server as a background process; the handle returns immediately
sandbox.process.start("python3 -m http.server 8000")
# Other commands run concurrently in the same sandbox
response = sandbox.process.run(argv=[
"python3", "-c",
"import time, urllib.request as u; time.sleep(1); print(u.urlopen('http://localhost:8000').status)",
])
print(response.stdout)Capacity and throughput
Fleet size operates within per-sandbox platform caps and your organization's credit balance.
| Control | What it limits | Scope |
|---|---|---|
| Resources | Maximum vCPU, memory, and disk of a single sandbox | Sandbox |
| Credits | Spending across sandboxes; creates are rejected when the balance is exhausted | Organization |
Reclaiming capacity
Delete sandboxes when their work is done to release compute and storage:
- Sandboxes release compute and storage immediately on delete.
- Spot sandboxes are deleted automatically when the platform needs capacity. See preemption.
Operating at scale
At high creation rates, two practices keep an application efficient:
- Make creates safe to retry with an idempotency key: a retried create with the same key returns the same sandbox instead of minting a new one.
- Wait with long-polls, not tight polling. The SDKs block on create until the sandbox runs. On the API,
waitlong-polls one sandbox, and the batch wait endpoint waits on up to200sandboxes over one connection, returning once one reaches the target state ortimeout_mselapses.
# Wait for one sandbox to reach running without tight polling
curl 'https://api.daytona.com/sandboxes/{sandboxId}?wait=running' \
--header 'Authorization: Bearer YOUR_API_KEY'
# Wait on a whole batch over one connection (up to 200 IDs)
curl 'https://api.daytona.com/sandboxes/batch-wait?ids={sandboxId1},{sandboxId2},{sandboxId3}&wait=running&timeout_ms=60000' \
--header 'Authorization: Bearer YOUR_API_KEY'