TL;DR — the headline numbers
Production state, end of Q1 2026, measured over 30 sequential cold-start iterations (matchesscripts/bench-reliability.py).
Two columns because where your client runs dominates the wall-clock
number — your in-cloud agent never pays the residential last-mile tax:
Server-side compute is single-digit ms; everything else is the
network between you and the nearest region. From an agent running
in any major cloud region the full create+exec+close round-trip
lands at p50 = 43 ms, p95 = 78 ms — measured from a Podflare host
benching against itself, which has the same network shape as any
nearby cloud customer.
For head-to-head comparisons against E2B, Daytona, and Blaxel, see
vs E2B, Daytona, and Blaxel — TL;DR:
Podflare wins every percentile (p50 / p95 / p99 / max).
~100 ms full round-trip from a fiber uplink or in-cloud. The
187 ms p50 above was measured from a laptop on residential wifi,
which adds ~100–150 ms of last-mile jitter on top of the actual
server-side compute (single-digit ms). From a fiber-uplink desktop,
a VPS, or another cloud region in the same metro, you can expect
the full
create + exec + destroy flow to land around 100 ms p50
with similarly tight p95/p99. Reproduce with
scripts/bench-reliability.py from wherever your agent actually runs.Headline: edge-routed hot path
What a long-running agent actually looks like — one Sandbox, many execs. This is the number that matters most.Hot run_code() — already-live sandbox
A full HTTPS
POST /v1/sandboxes/:id/exec with NDJSON streaming back.
Python interpreter, vsock marshalling, the works. 46 ms p50 is what
an LLM agent loop sees per tool call — measurably faster than E2B
(180 ms) and Daytona (182 ms) because we use vsock instead of an
in-VM HTTP server.
Full round-trip — Sandbox() → run_code() → close()
100 sequential iterations via api.podflare.ai (Cloudflare Worker →
nearest origin, haversine-routed), SDK ≥ 0.0.20. Two vantage points —
your real number is whichever matches where your agent runs.
Both columns cover create + exec + destroy + 3 HTTPS round-trips.
The residential column adds ~100–150 ms of last-mile wifi/ISP jitter
on top of the in-cloud number. The in-cloud column was measured
benching us-west’s hostd against itself — same network shape as any
customer agent running in a nearby cloud region.
SDK 0.0.20 defaults to
api.podflare.ai, the Cloudflare Worker
fronting every region. CF’s edge PoP is usually closer to the caller
than any individual region origin — from a US west-coast laptop, the
edge is ~5–15 ms away versus ~30–50 ms direct to us-west — and the
Cloudflare backbone to origin is cleaner than the public-internet
route. Counter-intuitive but reproducible: the “extra hop” is shorter
wall-clock than going direct.
Where the p95/p99 fix came from (SDK 0.0.19)
Pre-0.0.19 the same bench showed p99 = 1,741 ms and max = 2,290 ms. That “looked” like public-internet TCP SYN drops (0.05–0.35 % across our hosting fleet get dropped, which Linux turns into 1 s → 3 s → 7 s retransmits). It wasn’t. SDK 0.0.17 tried to fix it by capping the connect timeout at 800 ms withretries=2 on a fresh socket. That backfired on residential
wifi: a slow-but-real TLS handshake (900 ms due to noisy local DNS)
gets killed at 800 ms, retried (killed again), retried (killed again)
— three ConnectTimeouts chained together at ~2.9 s. Self-inflicted.
SDK 0.0.19 fixes it properly:
fork() — the 100 ms primitive
Copy-on-write mid-flight snapshot + reflink rootfs. One parent, N
children, each starting from the parent’s exact state.
Where the 24 ms goes on the server side:
The first fork from a fresh parent pays ~90 ms extra because the parent
has been running long enough to dirty ~20 MB of pages — those have to
hit disk once. On subsequent forks there’s nothing new to dirty and the
snapshot stays in the single-digit ms range.
Under the hood — internal latencies
These are the hostd-local numbers (loopback, no network). They’re what the customer-facing numbers above build up from.Pool refill: 12 ms
Rootfs clones are metadata-only — no block copy — because of the
filesystem we use on the host. On a default filesystem the same step
takes 700+ ms; that’s the difference between a warm pool that
keeps up and one that doesn’t.
Snapshot-load: 3 ms
Seed memory is shared across every pool VM with page-level copy-on-write, so kernel page cache is hit most of the time. Only pages the child actually dirties get copied out.Which URL should I hit?
Short answer: just callSandbox() with no arguments. As of SDK
0.0.20 that goes to api.podflare.ai — the Cloudflare Worker that
haversine-routes to the nearest origin. From most caller geographies
it’s faster than hand-pinning a region URL, because the CF edge PoP
is closer than any individual origin and CF’s backbone to the origin
is cleaner than the public-internet route.
The full picture, in order of preference:
Measured from a California laptop, 100 iterations each, SDK 0.0.20:
When to override the default
- Your agent runs in the same DC as a specific region (e.g. a
Latitude-hosted worker talking to
usw1). Direct skips the ~15 ms edge overhead and the CF backbone hop — both of which are pure latency when you’re already one rack away from the origin. - Hard region pinning for compliance —
Sandbox(region="eu")forces traffic to Helsinki regardless of where you’re calling from.
Scaling ceiling (single host)
On our current hardware (AMD EPYC 24-core, 96 GB DDR5):
Idle warm VMs use far less RAM than their nominal allocation —
Our Pod runtime’s COW + lazy snapshot restore means the guest only
commits pages it actually touches. We measured ~40 MB RSS per idle
1 GB warm VM under steady-state, so a 120-warm pool burns ~5 GB of
the box’s 93 GB available. The other 88 GB is headroom for
on-demand customer creates and Space resumes.
Scaling ceiling (multi-region)
Five regions live today, 544 warm sandboxes ready for instant hand-off across the fleet:
Routing happens at the Cloudflare Worker fronting
api.podflare.ai:
server-side haversine using Cloudflare’s per-request cf.latitude /
cf.longitude picks the closest origin. SDK 0.0.20 defaults here —
pre-0.0.20 clients with client-side timezone routing still work, but
the default has moved to edge-routed because CF’s edge PoP is usually
closer to the caller than any individual origin, and the CF backbone
to origin is cleaner than the public-internet route.
The default can be overridden:
- Explicit
region="us-east"in the SDK orX-Podflare-Regionheader in raw HTTP - Explicit
/r/REGION/...path prefix (e.g./r/us-east/v1/sandboxes) - Direct region URL via
Sandbox(host="https://use1.podflare.ai") - Automatic Worker failover on 5xx (for create-class requests only)
api-router/src/regions.ts with its coordinates
and the Worker picks it up the next deploy. SDK clients learn it via
the response endpoint header even before an SDK publish.
Distance routing examples
Today’s numbers
Production state, end of Q1 2026. All five regions (us-west · us-central · us-east · eu · sg) report the same shape:
For context vs other AI-agent sandbox platforms, see
vs E2B and Daytona — same harness, same
machine, same minute. Podflare cold-start is 2.2× faster than E2B
and 2.9× faster than Daytona in head-to-head benches.
Roadmap
- UFFD lazy memory paging — replace eager
MAP_PRIVATEmmap on snapshot resume with userfaultfd-served on-demand pages. Estimated 50–100 ms off pool-refill time, gated on real production data (waiting foron_demand_boot_ms_meanfrom the new pool-stats observability to justify it). - Memory prefetch mapping — record the pages a guest touches during cold-start at template-build time, replay on resume in a background thread. Phase 2 after UFFD lands.
- RAM-backed fork snapshots — fork diff writes hit RAM, not disk.
- Seed-tree templates — per-workload pre-imported snapshots. The
python-datascitemplate already haspandas + numpy + scipyimported in the REPL before you get the sandbox. - us-east region promotion — flip
continents: ["NA", "SA"]on us-east in the Worker (currently distance-routed only). Cuts geography variance for east-coast NA callers. - In-sandbox
envd-compatible API — Drop-in surface for thee2b_code_interpreterSDK so customers can repoint atapi.podflare.aiwith zero code change.
Compared to what?
V8 isolates (Cloudflare Workers) spawn in ~1 ms with ~1 MB memory. They’re an entirely different product: JS/Wasm only, no native deps, no filesystem, no Python REPL state. Real agents that runpip install scikit-learn && model.fit(X) don’t run in isolates.
Container-only platforms without snapshot-restore quote “cold start”
times that are really docker run + runtime init. A Python container
takes ~500 ms–2 s to become usable. Podflare’s warm pool hit is
10–50× faster and the sandbox is already-ready for run_code.
E2B and Daytona are the two other major AI-agent sandbox platforms.
We benchmarked all three head-to-head in the same minute on the same
machine — see vs E2B and Daytona for the
full numbers. TL;DR: Podflare cold-start is 2.2× faster than E2B and
2.9× faster than Daytona, mostly because of our vsock-based exec
path (46 ms first_exec vs their 180 ms).
What we have that they don’t:
- ~80 ms
fork()— copy-on-write diff snapshot + N parallel microVM spawns. Neither E2B nor Daytona expose fork. - Persistent Spaces — freeze-to-disk on idle, resume into a fresh sandbox later. The VM’s running Python process survives. Both competitors only support container-commit-style snapshots.
- 5-region edge routing with haversine geo + automatic failover. E2B and Daytona are single-region per cluster.
Reproduce the numbers
Every number on this page was produced by the bench script in our repo:Methodology
- Client: macOS laptop on regular residential wifi (west-coast US). This is not the best case. Last-mile wifi + consumer router buffering add roughly 100–150 ms of round-trip time that isn’t there on fiber-uplink desktops or cloud-to-cloud traffic.
- Network path (direct): Laptop → TLS → Caddy on
usw1.podflare.ai→ hostd (Latitude SJC bare metal). - Network path (edge): Laptop → Cloudflare edge →
api.podflare.aiWorker → origin → hostd. - Sandbox: Stock
defaulttemplate. 1 GB RAM, 4 GB rootfs, pool-warm. - SDK:
podflare==0.0.20(Python) — defaults toapi.podflare.ai, which is Cloudflare-edge-routed to the nearest origin. Single shared httpx Client withconnect=2.5 s+retries=1. Connection reuse matches what real agent loops do (they don’t open a fresh connection per exec). - N: 5 cold-start iterations end-to-end + 30 hot-exec iterations after one discarded warmup. Median reported. Cold-cold first call preserved (not discarded — it’s a real customer experience).
- Date: April 2026.
scripts/bench.py runs every iteration back-to-back and reports
statistics.mean + percentiles over the raw samples.
What you’ll see from a fiber uplink or in-cloud
If your agent runs on a VPS, a fiber-uplink desktop, or a nearby cloud region, coast-to-coast RTT drops from ~50 ms on wifi to ~20 ms on fiber and ~5 ms inside the same metro. Apply that delta to each HTTPS round-trip in the numbers above:- Hot
run_code(): 38 ms on wifi → ~15 ms on fiber → sub-10 ms in-cloud - Full round-trip: 226 ms on wifi → ~100 ms on fiber → ~30 ms in-cloud

