Sandboxes on Google Kubernetes Engine grew 16x in under five months. Not 16% — sixteen times. LangChain and Lovable are now running millions of AI agents through it, and Lovable alone pushes more than 200,000 new AI-generated projects a day across that infrastructure. The reason isn't a marketing push. It's that Kubernetes SIG Apps shipped something that didn't exist before: an upstream, vendor-neutral primitive for running untrusted, LLM-generated code safely, on a cluster you already operate.
That raises a very specific question for anyone running a self-hosted PaaS on Cluster API: do you adopt this primitive directly on your own nodes, or keep paying a third-party sandbox vendor like E2B, Daytona, or Modal to solve a problem Kubernetes itself now solves? This post works through what the CRD stack actually looks like, what it gives you for free versus what those vendors charge for, the real cost math, and — just as important — what's still missing before you can call it done.
What Agent Sandbox Actually Is
Agent Sandbox is a Kubernetes SIG Apps subproject, previewed at KubeCon NA in November 2025 and generally usable on any cluster today — not a GKE-only feature, though Google's own GKE Agent Sandbox (now GA) is the most visible deployment of it. At its core sits a new CRD:
apiVersion: agents.x-k8s.io/v1beta1
kind: Sandbox
metadata:
name: my-sandbox
spec:
podTemplate:
spec:
containers:
- name: my-container
image: <IMAGE>A Sandbox is a declarative wrapper around a single, stateful pod with a stable identity and persistent storage — the shape an agent runtime actually needs (one long-lived, addressable execution context per agent session), which a bare Deployment or Job was never designed to guarantee. Three extension CRDs build fleet operations on top of that primitive:
SandboxTemplate— a reusable spec for creating many similar sandboxes without repeating pod config.SandboxWarmPool— a pool of pre-warmed sandboxes kept ready so allocation doesn't pay a cold-start tax:
apiVersion: extensions.agents.x-k8s.io/v1alpha1
kind: SandboxWarmPool
metadata:
name: urunc-pool
spec:
sandboxTemplateRef:
name: urunc-python-sandbox
replicas: 3SandboxClaim— the request that pulls a ready sandbox out of a warm pool, abstracting the pod details away from whatever's asking for one.
Isolation is pluggable at the runtime-class level: gVisor's userspace kernel intercepts syscalls to shield the host, or Kata Containers hands each sandbox a real, hardware-virtualized kernel via QEMU. Either way, it's a RuntimeClass field on the pod spec, not a different product.
What You Get for Free vs. What Vendors Sell
The interesting part isn't that this CRD exists — it's what adopting it changes about the buy-vs-build calculus for a platform that already runs its own Kubernetes clusters.
| Agent Sandbox (upstream) | E2B | Daytona | Modal | |
|---|---|---|---|---|
| Isolation | gVisor or Kata (pluggable) | Firecracker microVM | Firecracker microVM | Proprietary container runtime |
| Self-host story | Native CRD, runs on any cluster you already operate | Nomad-based, AWS/GCP only | Helm chart, but manual K8s ops | Managed-only, no self-host |
| Pricing model | Your own compute cost | ~$0.0504/vCPU-hr + $0.0162/GiB-hr | ~$0.0504/vCPU-hr + $0.0162/GiB-hr | ~$0.0000131/core-sec (cheaper at scale) |
| Warm-start handling | SandboxWarmPool (built in) | Vendor-managed | Vendor-managed | Vendor-managed |
| GA maturity | GA on GKE; upstream CRDs at v1beta1/v1alpha1 | GA, production since 2024 | GA | GA |
For a platform that already runs Cluster API–managed nodes — which describes bex and describes most self-hosted PaaS deployments — the upstream CRD path means the isolation and fleet-management logic (warm pools, claims, templates) ships as Kubernetes-native objects your existing controllers, RBAC, and observability stack already understand. You're not standing up a second orchestration plane (E2B's Nomad control plane) or bolting on a managed SaaS billing relationship (Modal) just to get safe agent execution. kubectl get sandboxes, kubectl logs, and every existing NetworkPolicy and admission webhook you already run against pods keep working against sandboxes too, because a Sandbox compiles down to a pod at the API level.
What you still have to build yourself is per-tenant isolation at the Kubernetes RBAC layer — the CRD gives you the pod-level primitive, not a multi-tenant access model. In practice that means a Namespace per tenant (or per tenant tier), a Role scoped to sandboxes.agents.x-k8s.io resources within it, and a RoleBinding tying the tenant's service account to that role — so tenant A's control-plane calls can create and claim sandboxes in tenant A's namespace and nowhere else:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: sandbox-operator
namespace: tenant-acme
rules:
- apiGroups: ["agents.x-k8s.io", "extensions.agents.x-k8s.io"]
resources: ["sandboxes", "sandboxclaims"]
verbs: ["create", "get", "list", "delete"]That's a few hours of YAML and a controller reconciling namespaces against your tenant table — not a new distributed system. Compare that to onboarding a vendor: negotiating a BYOC contract, standing up billing reconciliation against their metered API, and building the same tenant-scoping logic anyway on top of their API instead of Kubernetes' own.
The Cost Math, With the Caveat That Matters
Here's where a self-hosted comparison usually oversells itself, so the honest version first: owned compute only beats per-second vendor billing above a utilization threshold. A sandbox fleet idling at 20-30% utilization on owned hardware can easily cost more per useful second than E2B's or Daytona's metered rate, because you're paying for the whole node whether an agent is running in it or not. The comparison only favors self-hosting once your sandbox workload is dense enough that idle capacity stops dominating the bill — which is exactly the case SandboxWarmPool is built to help with, since it recycles the same warmed pool across many short-lived agent sessions instead of provisioning one node per session.
With that caveat stated, the raw numbers: E2B and Daytona both charge roughly $0.0504 per vCPU-hour and $0.0162 per GiB-hour for managed sandboxes. A Hetzner dedicated/cloud vCPU-hour under Cluster API runs a small fraction of that once amortized across a reasonably utilized fleet — the same owned-hardware economics that make bex's core pitch (run your own machines instead of renting a hyperscaler's markup) work for application hosting also apply to sandbox hosting, provided you're running enough concurrent agent sessions to keep the pool warm rather than idle.
Put a number on "reasonably utilized": at E2B/Daytona's rate, 100 sandboxes running continuously for a month (2 vCPU, 4 GiB each) bills out to roughly $0.0504 × 2 + $0.0162 × 4, or about $0.166/hr per sandbox — call it $12,000/month for the fleet. The same 100-sandbox footprint on owned Hetzner capacity, sized to actual concurrent usage rather than one node reserved per sandbox, typically lands in the low thousands per month once you're running dense enough that a SandboxWarmPool is recycling pods across sessions instead of provisioning a fresh node per claim. The gap closes fast, though, if your real concurrency is 20 sandboxes instead of 100 spread across the same reserved nodes — at that utilization, the vendor's per-second billing can beat your own idle capacity outright. Measure your actual concurrent-session count before committing capacity, not your peak-hour guess.
The performance bar you need to clear to make that trade worthwhile is public: GKE's Agent Sandbox integrated warm pool allocates 300 sandboxes per second per cluster, at sub-second latency, with 90% of allocations completing in under 200ms — up to a 90% improvement over cold container starts. That's the number a self-hosted SandboxWarmPool deployment on your own Cluster API nodes has to approach before "we built it ourselves" is actually a win over "we paid a vendor for a working answer on day one."
What's Not Ready Yet
The honest gap: as of mid-2026, upstream Agent Sandbox ships gVisor and Kata Containers isolation — solid, production-grade, but not the hardware-level Firecracker microVM isolation E2B and Daytona have offered since their inception. Firecracker and QEMU support are explicitly 2026–2027 roadmap items for the project, not shipped today. If your threat model requires microVM-grade isolation specifically (not just gVisor's syscall interception), the upstream primitive isn't there yet — Kata Containers' QEMU-backed option gets closer, but it's a heavier resource footprint than gVisor and isn't the same battle-tested Firecracker stack.
The same applies to framework integration: native "plug-and-play" support for Ray and CrewAI is roadmapped, not current. If your platform is framework-agnostic — you just need a pod that runs arbitrary agent-generated code, not a first-class Ray actor — this gap doesn't block you. If you were hoping to hand a SandboxClaim directly to a CrewAI orchestrator with zero glue code, that integration doesn't exist yet.
One more forward-looking item worth tracking rather than waiting on: PVC-based scale-to-zero, which suspends an idle sandbox while preserving its persistent volume, aiming for near-zero idle compute cost with full state retention on resume. That directly addresses the utilization caveat above — it's the mechanism that could push the break-even point for self-hosting lower over time.
What a Cluster API–Based PaaS Should Actually Do
Adopt the Sandbox CRD now for gVisor-isolated execution on nodes you already run — it's GA-adjacent, upstream, and solves the fleet-management problem (templates, warm pools, claims) you'd otherwise have to hand-roll. Treat Firecracker/QEMU support as a 2027 upgrade path you migrate to when it lands, not a reason to wait — gVisor's syscall-interception model is already a legitimate isolation boundary for most agent-generated-code threat models, and Kata Containers is available today if you need stronger isolation sooner. Don't wait on Ray/CrewAI native integration if your platform stays framework-agnostic; that gap only matters if you're building specifically around one of those orchestrators. And size your warm pool against real utilization data before assuming self-hosting wins — the math only works once idle capacity stops eating the savings.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. If you're already running Cluster API–managed nodes, wiring the upstream Sandbox CRD into your own control plane is a smaller lift than standing up a second vendor relationship for AI-agent execution. Star the repo on GitHub or deploy your first app today.