Cloudflare Kitesurf: An Agent-First Browser That Uses 3-7x Less Memory Than Chromium
Cloudflare shipped Kitesurf on August 6, a web browser it wrote from scratch for AI agents. It runs entirely inside Workers. No Chromium underneath, no container, no headless Chrome process idling in a warm pool waiting for something to do.
The problem it targets is a billing problem. Agents need browsers to do real work, and Chromium is the only serious option, but Chromium was built for a person sitting in front of a screen. Tabs, extensions, device sync, sixty frames a second of smooth scrolling. An agent does not care about any of that. What it cares about is token count, context window, and what the session costs. Handing every agent its own Chromium instance prices most agentic applications out of the web entirely, and leaves browsing to the expensive models that can afford it.
So Cloudflare threw out the human-facing half and kept the rest.
What’s actually inside
Kitesurf started as a port of obscura, a headless Rust engine with no Chrome and no Node.js dependencies. Cloudflare pointed an AI agent at it and tried to move it onto Workers. The first attempt went badly. Once the agent had a detailed plan and a clear definition of success it could loop against, it worked, and the team built out from there.
Four components do the work.
The Engine is the only public-facing piece. It speaks the Chrome DevTools Protocol over WebSocket, exposes HTTP REST endpoints, and holds session state. Everything else is stateless by design.
PageScript spins up a fresh isolate per page or out-of-process iframe using Dynamic Workers, with a clean globalThis and a DOM document. HTML and CSS parsing comes from Blitz, a modular Rust rendering engine, paired with Stylo, Firefox’s CSS parser. Scripts and Wasm files execute inside that same isolate.
Eval was the awkward part. Workers still block eval for security reasons, and spinning up another isolate would lose access to globalThis. The workaround is Boa JS, an ECMAScript engine written in Rust, compiled to run on Workers. A runtime on top of a runtime. Cloudflare admits this is not optimal and plans to drop it when native eval support lands.
PageRenderer turns the computed page into pixels. It pulls the scene from PageScript, fetches fonts and images from Static Assets, rasterizes into a buffer, and hands back a JPEG, PNG, or PDF. Because it holds no state, the Engine can kill and relaunch it on any stuck call.
SandboxOutbound is the only component allowed to touch the network. Dynamic Workers enforce that. It handles CORS, injects browser-shaped headers, filters responses, and keeps each page’s cookies in a separate jar. Anything that fails policy gets a 403.
The numbers, including the one that goes the other way
Across a fourteen-URL corpus, medians of five runs:
| Metric | Kitesurf | Chromium (warm pool) |
|---|---|---|
| CPU, screenshot | 380 ms | 1,173 ms |
| CPU, HTML extraction | 229 ms | 877 ms |
| Memory, screenshot | 57.8 MiB | 271.0 MiB |
| Memory, HTML extraction | 39.4 MiB | 273.7 MiB |
| Wall time, screenshot | 1,148 ms | 637 ms |
| Wall time, HTML extraction | 820 ms | 472 ms |
Kitesurf wins CPU and memory by three to seven times. Chromium wins the stopwatch by roughly 1.7x, because a JIT that has already seen a page beats a cold software renderer. Cloudflare says most of that gap sits in rasterization and image encoding, and is being worked on.
Worth reading those rows carefully before switching anything. If your pipeline is latency-bound, Kitesurf is currently slower. If it is cost-bound and bursty, which describes most agent fleets, the memory column is the whole argument.
The 215,000 test figure needs an asterisk
Kitesurf passes more than 215,000 Web Platform Tests, with hundreds added weekly. That sounds enormous, and it is a real signal on DOM, CSS, HTML, selection, SVG, and XHR coverage.
But WPT measures conformance to W3C standards, not whether a real website renders. Cloudflare knows this, which is why they built a separate harness running multi-step Puppeteer tests against both Chromium and Kitesurf, comparing assertions and rendering output at every step. The WPT number is the headline. The visual regression suite is the honest test.
Working today: TodoMVC across vanilla, React, Vue, Angular and Preact, plus Wikipedia, Hacker News, and much of the Cloudflare dashboard. Not working: video, WebGL, bot challenges that check real TLS fingerprints, and long authenticated sessions that need persistent state. For those, Browser Run’s Chromium default stays.
Switching costs almost nothing
Existing Puppeteer, Playwright, chrome-remote-interface, and MCP clients all work already. Add browser=kitesurf to a Browser Run CDP or Quick Action endpoint and you are on it. Free while in beta, behind per-account limits. There is a public playground with Chrome DevTools injected, including a Memory panel that reports the WebAssembly footprint of each isolate.
Cloudflare says it will open source Kitesurf once it is ready, so customers can deploy their own version on their own accounts.
The project is twelve weeks old. First commit in May.
That timeline is the part worth sitting with. A browser engine used to be a decade of work and a reason companies gave up. This one got built in a quarter by a small team that let agents grind against a test suite while humans handled architecture. Whether or not Kitesurf itself lasts, the method is going to get copied.