Sandboxes vs Functions
Daytona's two execution primitives and when to reach for each.
Daytona gives you two ways to run code, and choosing the right one is the first design decision for any workload. A sandbox is a machine you hold: you create it, interact with it over time, and delete it when you are done. A function is code you call: you deploy a container handler once, then invoke it on demand while Daytona starts, scales, and tears down the machines behind it. Both run on the same hardware-isolated microVMs and give the same strong isolation — they differ in who manages the lifecycle and how you interact with them.
The distinction in one line
- Sandbox — "give me a machine I control." You own its lifecycle and talk to it directly (exec, files, SSH, ports).
- Function — "run this code when I ask." Daytona owns the lifecycle; you send a request and get a response, and it scales to zero when idle.
Side by side
| Sandbox | Function | |
|---|---|---|
| Mental model | A machine you hold and interact with | Code you call on demand |
| You manage | Its full lifecycle (create → use → stop/delete) | Only the deployment; instances are managed for you |
| How you interact | Toolbox (exec, files, git, sessions), SSH, exposed ports | Invoke over HTTP (sync, async, or fan-out) |
| Scaling | You create as many as you need | Automatic; scales to zero when idle |
| State between uses | Persists in the sandbox (and can be persistent across stops) | Each invocation is independent; instances are ephemeral |
| Billing | While the sandbox exists (compute; storage if persistent) | Per invocation duration only |
| Best for | Interactive work, agents that need a workspace, long or stateful tasks, dev environments | Webhooks, on-demand jobs, batch fan-out, scheduled tasks, stateless tools |
When to use a sandbox
Reach for a sandbox when the work needs a place: an agent that clones a repo and iterates on it, an interactive session a person SSHes into, a long-running job, or anything that accumulates state you want to inspect, snapshot, or fork. You decide when it starts and stops, and you can talk to it directly the whole time it is alive.
When to use a function
Reach for a function when the work is a call: a request comes in, code runs, a result comes back, and there is nothing to hold onto afterward. Because functions scale to zero, you pay nothing between calls and nothing for idle capacity — ideal for spiky or scheduled workloads. Deploy a container that serves HTTP, then invoke it synchronously, asynchronously, or as a fan-out map; run it on a schedule; or expose it as a public web endpoint.
Using both together
The two primitives compose. A common pattern is an agent running in a long-lived sandbox that calls functions for isolated, parallelizable steps (for example, running untrusted generated code, or fanning out an evaluation across many inputs), keeping the orchestration stateful while the heavy lifting scales elastically and bills per call.