AI Sandbox Networking Compared: Tensorlake vs E2B vs Daytona vs Fly.io Tensorlake redesigned its sandbox proxy to collapse a second Layer 7 hop down to Layer 4, publishing before-and-after numbers for the change, according to a comparison of sandbox networking across Tensorlake, E2B, Daytona, and Fly.io. The gateway-to-forwarder hop still authenticates with mTLS, and the L4 forwarder reads a short authenticated routing preamble once per connection before splicing bytes through. Because the L4 forwarder can no longer see individual requests, Tensorlake derives sandbox activity from byte flow, tracking bytes moved per tunnel and periodically reporting the count to the dataplane to reset the sandbox's idle timer. Every sandbox platform for AI agents runs into the same problem on day one. A request from the open internet has to reach an isolated microVM or container, and something has to decide where that request goes before either side trusts the other. That “something” doesn’t have to be a single hop. A sandbox ingress path can run through several proxies in sequence, an edge gateway, then something deeper inside the platform’s own network, before a request ever reaches the sandbox. Each hop makes its own choice about how much of the traffic it actually looks at. A hop can operate at Layer 4, moving TCP or TLS bytes around without looking at what’s inside them. Or it can operate at Layer 7, parsing every HTTP request and making a decision based on what it finds. Tensorlake is a good example of why that’s a per-hop choice, not a whole-path one : it keeps its outer edge gateway at L7, and the change this piece spends the most time on is a second hop, further into its dataplane, that moved from L7 down to L4. I spent a few days reading how four platforms document this hop. I went in expecting four minor variations on the same idea. I came out with something more interesting: three platforms that document the mechanism well and one that documents the mechanism and shows its work on why it’s built that way. That gap is what this piece is about. One quick note before diving in: Modal sits this comparison out, its inbound-access model is well documented and secure by default, but the actual routing mechanism behind a public URL isn’t documented at the depth the other four platforms here document theirs. Here’s the tradeoff, stated once, before any vendor gets involved. An L7 proxy parses every request. It can read headers, make a fresh routing call, rewrite something, check a token, all per request. That flexibility isn’t free. The proxy has to understand the protocol it’s forwarding, and it pays a CPU cost for that understanding on every single request that crosses it. An L4 proxy skips the understanding entirely. Once a connection is set up and the proxy knows where it’s headed, it can move bytes at close to zero per-byte overhead, often using kernel primitives like splice that never copy the payload into userspace at all. The catch: it can't see inside the connection anymore to make a new call. Whatever logic you needed has to get decided once, up front, not per request. So which one wins? Depends entirely on what’s crossing the hop. That second row is where an L4 hop earns its keep. Keep that in mind, because it’s the whole reason Tensorlake’s numbers below look the way they do. This is the one platform in this piece that changed its own architecture and published before-and-after numbers for the change. Here’s the mechanism first, numbers after. Tensorlake’s sandbox proxy used to run two Layer 7 hops back-to-back: That second hop being in-process with the orchestrator wasn’t a small detail. It meant a routine orchestrator deploy could interrupt a live connection passing through the proxy, because the two things weren’t separable. That’s the kind of coupling you don’t notice until a deploy lands mid-transfer. The redesign collapsed the second hop from L7 down to L4: The gateway-to-forwarder hop still authenticates with mTLS mutual TLS . The forwarder reads a short authenticated routing preamble once, at the start of a connection, before it starts splicing bytes through. There’s a second problem an L4 hop creates that’s easy to miss: the dataplane still needs to know when a sandbox is still active, so it can extend the idle timeout. An L7 proxy got that for free, it saw every request go by. The L4 forwarder can’t see requests anymore, so Tensorlake derives activity from byte flow instead: the forwarder tracks bytes moved per tunnel and periodically reports that count to the dataplane, which uses it to reset the sandbox’s idle timer. Same signal, different source. The forwarder also runs kernel TLS. This is a narrower change than it sounds. It moves only the TLS record layer into the kernel, the payload is still encrypted and decrypted exactly as before. What’s different is that it’s no longer staged and parsed in userspace to get there, which is what makes splice usable on the encrypted path. And here’s a detail I appreciate more than I probably should: there’s no fallback. The daemon refuses to start if the kernel can’t attach the TLS ULP upper-layer protocol , full stop. It needs Linux 5.1 or newer, TLS 1.3, and a pure software stack. No quiet degradation, no “best effort.” If your kernel can’t do it, the thing doesn’t boot. That’s a real design decision, and it’s the kind a lot of teams fudge. Now, the numbers. Worth being precise about the test conditions before looking at them: one connection, one direction, over loopback, on a single desktop-class machine, moving 4 GB per run. That’s a controlled measurement of the proxy path itself, not a real network path with real latency and jitter sitting in front of it. Removing the redundant L7 hop did most of that work by itself, on both throughput and CPU. Kernel TLS and splice added roughly another 20% of throughput on top. Two separate wins, worth keeping separate in your head. Of the forwarder’s own CPU budget, cryptographic operations account for about a quarter of it, and I want to be precise about that: a quarter of the forwarder’s CPU, not a quarter of the system. One more thing worth saying plainly, because it’s easy to want it to be true: none of this measures end-to-end latency for an actual agent’s HTTP call. It measures bulk-transfer throughput and forwarder CPU, one connection at a time. A short API call is bound by handshake and round-trip time, not payload size, so this fix doesn’t directly touch that traffic shape. It’s the right fix for what it targets, and it doesn’t pretend to be more than that. E2B puts a component called Client Proxy at the edge, separate from the control-plane API. It’s an L7 router in the plain sense: it parses the host header, looks up which node the sandbox is currently running on in a Redis routing catalog, and reverse-proxies the request to that node. That’s not the last hop, though. The node itself runs a second proxy, inside the orchestrator process, that takes the request the rest of the way into the VM. You can see the routing scheme in the URL itself. A sandbox exposing port 3000 gets a public address like 3000-