Skip to content
Back to blog
Open Source

Sub-90ms Cloud Code Execution: How Daytona Replaced Docker in Our AI Agent Stack

Vstorm · · 5 min read
Available in: Deutsch · Español · Polski
Table of Contents

Every AI agent that writes code needs somewhere to run it. The agent generates a Python script, a shell command, a data pipeline — and something has to execute that code safely, isolated from your production environment.

For the last year, we used Docker. Spin up a container, run the code, tear it down. It works. But “works” comes with a cost: 2-5 seconds of cold start latency per sandbox. When your agent is making 10-20 tool calls per task, that’s 30-100 seconds of just waiting for containers to start.

Then we tried Daytona. Sub-90ms startup. No Docker daemon. Ephemeral cloud sandboxes that spin up faster than your agent can think of the next step.

The Problem: Docker Cold Starts Kill Agent UX

Our AI agents use pydantic-ai-backend — a Python library that provides file storage and code execution backends for Pydantic AI agents. Before Daytona, we had three backends:

BackendStorageExecutionUse Case
StateBackendIn-memoryNoTesting, ephemeral sessions
LocalBackendFilesystemYesLocal development
DockerSandboxContainerYesMulti-user, untrusted code

Docker was our production choice. Isolated execution, controlled environment, no risk of agents destroying the host. But the startup overhead was real:

  1. Pull image (if not cached) — seconds
  2. Create container — hundreds of ms
  3. Start container — hundreds of ms
  4. Wait for health check — variable
  5. Execute the actual command — the only part that matters

Enter Daytona: Ephemeral Cloud Sandboxes

Daytona provides cloud-based ephemeral sandboxes — isolated VMs that pre-provision resources and eliminate cold start overhead. Sub-90ms from creation to first command execution.

We added DaytonaSandbox as a fourth backend in pydantic-ai-backend v0.1.12:

from pydantic_ai_backends import DaytonaSandbox, create_console_toolset
from pydantic_ai import Agent
from dataclasses import dataclass
@dataclass
class Deps:
backend: DaytonaSandbox
sandbox = DaytonaSandbox(api_key="dtna_...")
try:
toolset = create_console_toolset()
agent = Agent("openai:gpt-4.1", deps_type=Deps)
agent = agent.with_toolset(toolset)
result = agent.run_sync(
"Write a script that calculates fibonacci and run it",
deps=Deps(backend=sandbox),
)
print(result.output)
finally:
sandbox.stop()

Same agent, same toolset, same API — different backend. The agent doesn’t know (or care) whether it’s running in Docker or Daytona.

The Architecture: BaseSandbox Abstraction

To support Daytona alongside Docker cleanly, we extracted a BaseSandbox abstract base class:

class BaseSandbox(ABC):
"""Abstract sandbox backend for isolated code execution."""
@abstractmethod
def execute(self, command: str, timeout: int = 1800) -> ExecuteResult: ...
@abstractmethod
def _read_bytes(self, path: str) -> bytes: ...
@abstractmethod
def write(self, path: str, content: str | bytes) -> WriteResult: ...
def edit(self, path: str, old: str, new: str, replace_all: bool = False) -> EditResult:
# Default: read → Python string replace → write
...

Both DockerSandbox and DaytonaSandbox inherit from BaseSandbox. The toolset doesn’t care which one it gets.

MethodDockerDaytona
execute()docker.exec_run()sandbox.process.exec()
_read_bytes()Shell cat via Docker execNative file download API
write()Shell cat > via Docker execNative file upload API
stop()Remove containerDelete cloud sandbox

Daytona’s native file APIs are particularly interesting — instead of piping through a shell (which Docker does), Daytona uploads/downloads files directly through its SDK.

Docker vs Daytona: When to Use Which

FeatureDaytonaSandboxDockerSandbox
Startup timeSub-90ms2-5 seconds
InfrastructureCloud (Daytona platform)Local Docker daemon
Setup requiredAPI key onlyDocker installed + running
IsolationCloud VMContainer
CostDaytona pricingFree (local resources)
Best forCI/CD, serverless, cloudLocal dev, self-hosted

Use Daytona when: cloud deployments, startup latency matters, horizontal scaling, CI/CD pipelines where Docker-in-Docker is painful.

Use Docker when: running locally, need custom runtimes, want to self-host everything, cost-sensitive.

Setup: 3 Lines to Switch

# Before: Docker
from pydantic_ai_backends import DockerSandbox
sandbox = DockerSandbox(image="python:3.12-slim")
# After: Daytona
from pydantic_ai_backends import DaytonaSandbox
sandbox = DaytonaSandbox(api_key="dtna_...")

Install with the Daytona extra:

Terminal window
pip install pydantic-ai-backend[daytona]

Why Sub-90ms Matters

The raw number is impressive, but the real impact is on agent workflows:

Sequential tool calls compound. An agent solving a coding task might: read 5 files, plan, write 3 files, run tests, fix 2 files, run tests again. That’s ~15 tool calls. With Docker’s 2-second overhead per sandbox operation: 30 seconds of waiting. With Daytona: ~1.3 seconds total overhead.

Interactive agents need responsiveness. When a user watches the agent work in a terminal, every second of latency feels like lag. Sub-100ms makes execution feel instant.

CI/CD pipelines benefit most. In CI, you typically can’t run Docker-in-Docker easily. Daytona needs only an API key — no daemon, no privileged containers, no socket mounts.

The Composite Pattern: Best of Both

For complex setups, CompositeBackend routes different operations to different backends:

from pydantic_ai_backends import CompositeBackend, LocalBackend, DaytonaSandbox
backend = CompositeBackend(
backends={
"local": LocalBackend("/workspace"),
"sandbox": DaytonaSandbox(api_key="dtna_..."),
},
routing={"src/": "local", "tmp/": "sandbox"},
)

Read source files locally (fast, no overhead), execute untrusted code in Daytona (isolated, ephemeral). The agent doesn’t know — the composite routes each call.

Key Takeaways

  • Backend abstraction pays offBaseSandbox let us add Daytona without touching a single line of agent code or toolset logic
  • Sub-90ms is real — Daytona’s pre-provisioned VMs eliminate Docker’s cold start entirely
  • Docker isn’t dead — it’s still the right choice for local development and self-hosted setups
  • Agent UX is cumulative — 15 tool calls x 2 seconds of overhead = 30 seconds of pain. Small latency improvements compound

Try it: pydantic-ai-backend on GitHubpip install pydantic-ai-backend[daytona]

Share this article

Related Articles

Ready to ship your AI app?

Pick your frameworks, generate a production-ready project, and deploy. 75+ options, one command, zero config debt.

Need help building production AI agents?