Skip to content
Back to blog
Open Source

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

Kacper Włodarczyk · · 6 min read · Updated on March 4, 2026
pydantic-ai ai-agents python docker daytona
Table of Contents

TL;DR: Daytona replaces Docker as the code execution sandbox for AI agents, cutting cold start latency from 2-5 seconds per container to sub-90ms per cloud sandbox. For agents making 10-20 tool calls per task, this reduces total overhead from 30-100 seconds of container startup to roughly 1.3 seconds. The integration ships as DaytonaSandbox in pydantic-ai-backend v0.1.12, inheriting from the same BaseSandbox abstract class as DockerSandbox — switching requires changing 3 lines of code and needs only an API key, no Docker daemon. Daytona’s native file APIs upload and download files directly through its SDK rather than piping through shell commands like Docker does. The CompositeBackend pattern enables hybrid setups: read source files locally with zero overhead, execute untrusted code in Daytona with full isolation. Docker remains the right choice for local development and self-hosted setups, while Daytona excels in CI/CD pipelines where Docker-in-Docker is painful and cloud deployments where startup latency compounds across sequential tool calls.

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. We explored the Docker sandbox pattern in depth in our predictive AI Docker sandbox post.

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. This is especially relevant for open-source Claude Code alternatives that need sandboxed execution in diverse environments.

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

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?