Cloudflare's Kitesurf Loses To Chromium On Speed. Read The Memory Column Instead.
Cloudflare shipped a browser engine written for agents instead of people. Its launch benchmark admits it is 1.8x slower, and that admission is the most useful part of the post.
Cloudflare published a benchmark table for its new browser and two of the six rows say the new browser is worse. Screenshots take 1,148 milliseconds of wall time against Chromium's 637. HTML extraction takes 820 against 472. A vendor putting its own losses in the launch table is unusual enough to make you read the other four rows carefully, and the other four rows are where the argument lives.
Memory for HTML extraction: 39.4 MiB against Chromium's 273.7 MiB. That is a 7x gap, and it is the number Cloudflare wants you to look at.
Kitesurf launched on August 6 as part of Agents Week. It is a browser engine written in Rust, compiled to WebAssembly, running inside V8 isolates on Cloudflare Workers. It renders a smaller slice of the web than Chromium does, and it renders that slice less exactly. Both of those are design choices, not bugs on the roadmap.
The position: for agent work, the stopwatch is the wrong meter
Here is where I land. If your agent takes screenshots, pulls HTML, or generates PDFs at any real volume, wall time is a vanity metric and memory is the invoice. A headless Chromium instance holds roughly 270 MiB per session in Cloudflare's measurements. That number is what makes "one browser per agent" expensive, and expense is what keeps browser access limited to the models and budgets that can absorb it.
Kitesurf's pitch is that you can hand a browser to every agent if the browser costs 40 to 60 MiB instead of 270. Cloudflare says this out loud in the post: less memory means more sessions per machine, which lowers their cost and yours.
The counterargument deserves a full sentence rather than a shrug. Latency is not free. If a human is waiting on the agent, an extra 500 milliseconds per page compounds across a ten-step task into something a user notices. My read is that this splits cleanly by workload. Batch extraction, scheduled crawls, PDF generation, and evaluation harnesses should be measured in memory. Anything with a person watching a spinner should still be measured with a stopwatch.
How it works, and why the memory number drops
The mechanism explains the tradeoff better than the marketing does.
Kitesurf parses HTML and CSS using parts of Blitz, a modular Rust rendering engine, and Stylo, Firefox's CSS engine. Both are native Rust compiled straight to WebAssembly through wasm-bindgen rather than routed through an emulation layer. JavaScript runs inside the same isolate as the page. For eval, which Workers does not support natively for security reasons, Cloudflare runs Boa, an ECMAScript engine written in Rust. That is a JavaScript runtime running on top of a JavaScript runtime, and the post concedes it "doesn't seem optimal, and it isn't," but handles the occasional eval well enough.
The architecture splits into three parts. The Engine is the only public-facing piece, speaks the Chrome DevTools Protocol over WebSocket and HTTP, and is the only component that holds session state. PageScript spins up one long-lived isolate per page or out-of-process iframe, each with a clean globalThis and its own DOM. PageRenderer turns the computed page into pixels using blitz-paint and Parley for glyph shaping, then hands back a PNG, JPEG, or PDF.
One component touches the network. Everything else is walled off from it. SandboxOutbound fetches every asset, enforces CORS, injects browser-shaped headers, filters responses, and keeps each page's cookies in a separate jar. Anything that fails policy gets a 403. Cloudflare's stated assumption is that every page load is untrusted input and every session starts fresh.
That last design rule is why the memory number falls. There is no warm process pool to keep alive, no browser chrome, no tab model, no extension host, no profile on disk. The renderer holds no page state beyond a disposable cache, so the Engine can kill and relaunch it on any stuck call. Chromium is expensive partly because it is good at being a long-lived application for a person. Kitesurf is cheap because it is built to be thrown away.
It passes roughly 215,000 Web Platform Tests today, with the areas agents actually touch (DOM, CSS, HTML, selection, SVG, XHR) covered better than the areas they do not.
Read the whole table, not the headline
The launch summary says three to seven times less CPU and memory. That range is doing work, so here is the full set, all medians of five Browser Run quick-action runs across a curated 14-URL corpus:
| 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 |
The 7x figure is the best single cell in the grid. CPU savings run 3.1x to 3.8x. Memory savings run 4.7x to 7.0x. Wall time costs you 1.7x to 1.8x. If you quote "7x cheaper" to your team, you are quoting the memory row for one task type on a vendor's own corpus of fourteen URLs.
Cloudflare is straight about why it loses the stopwatch. A JIT that has already compiled a page beats a cold software renderer, and most of the remaining gap sits in rasterization and image encoding.
Put this into practice
The cost of trying this is one URL parameter, which is rare enough to be worth the twenty minutes.
- Open the public playground and paste in three URLs your agent actually hits. Not
example.com. The pages that break things. - Open the injected Chrome DevTools panel while it renders. Cloudflare wired up the Memory panel to report the WebAssembly footprint of each isolate, including frames, so you can see per-page cost directly instead of inferring it.
- Add
browser=kitesurfto a Browser Run Quick Action endpoint and diff the output against your current screenshot or extraction. The CDP endpoint takes the same parameter, so existing Puppeteer, Playwright, chrome-remote-interface, and MCP clients keep working unchanged. - Build a small corpus of your own. Fourteen URLs chosen by the vendor tells you what is possible. Thirty URLs chosen by your product tells you what is true for you.
- Route by task rather than switching wholesale. Send batch extraction and PDF jobs to Kitesurf, keep interactive and authenticated flows on the Chromium default, and set a fallback so a Kitesurf failure retries against Chromium instead of failing the task.
Honest limitations
Cloudflare names its own exclusions, which I appreciate, and the list is not short. No video playback. No WebGL. No negotiating a bot-challenge handshake with real TLS fingerprints. No ten-minute authenticated session that depends on persistent state. If any of those describe your workload, this is the wrong tool today and the post says so.
Beyond the named list, four things temper the numbers.
The corpus is small and curated. Fourteen URLs, chosen by the team shipping the product, run as medians of five. That is a reasonable smoke test and it is not an independent benchmark. Nobody outside Cloudflare has published one yet.
CDP support is a subset. Kitesurf implements enough of the protocol for most agents and automation tools, and "enough for most" is the kind of phrase that turns into a debugging afternoon when your client reaches for the method that is not there.
Pricing is unknown. It is free while in beta, behind per-account limits, which means the unit-economics argument that justifies the whole project has no price attached to it yet. The efficiency gain is real. Whether it reaches your bill depends on a number Cloudflare has not published.
The project is twelve weeks old, first commit in May, and the promise to open source it so customers can self-deploy is a promise, not a release. Kitesurf currently renders Wikipedia, Hacker News, TodoMVC across several frameworks, the Cloudflare blog, and much of the Cloudflare dashboard. That is a real list and it is also a short one.
The gap that bothers me most is a framing gap. The post opens by arguing that the threat model for agent browsing is different, naming prompt injection and tool safety as top priorities. The security engineering that actually shipped is isolation and egress control: one network component, per-page cookie jars, fresh sessions, disposable isolates. All of that is worth having. None of it is prompt-injection defense. A page can still return text that hijacks your agent's plan, and Kitesurf will render it efficiently. The isolation story is about protecting the browser. The injection story is about protecting the model, and it is still yours to solve.
Where this leaves you
The interesting thing about Kitesurf is not that Cloudflare built a browser. It is that they published the row where they lose and built the argument around a different column. That is a bet that the industry has been optimizing agent infrastructure against a metric inherited from human software.
You can test that bet cheaply this week. Take your three worst pages, run them through the playground, and look at the memory panel. If the number that comes back changes what you could afford to run, you have learned something about your architecture regardless of whether you ever ship on Kitesurf. If it does not, you have spent twenty minutes and you now know which meter your workload actually runs on.
Sources: Cloudflare, "Introducing Kitesurf"; Kitesurf playground; Browser Run documentation; Blitz; Stylo; Boa. Benchmark figures are Cloudflare's own, medians of five runs across a 14-URL corpus.