Browserheap

Research

Agents leave tabs open. We measured what that costs.

We opened the same 30 websites in every popular agent browser, ran 19 agent actions and 60 real sites through the lightweight engines, and gave the same AI agent real tasks on two browsers. Here is everything we found, including where we lost.

Summary

    01Why tabs pile up

    An agent doing research works like a person with too many tabs, minus the habit of closing them. It searches, opens five results, follows two links into docs, checks a forum thread and writes its answer. Every page it opened is still there, rendering, running scripts and holding memory, and the agent will rarely look at most of them again.

    People running agents feel this. On agent-browser, users report 60 or more tabs piling up with the browser above 100% CPU; the fix being discussed is an idle timeout that closes the whole browser. On browser-use, long-running agents collect tabs for days, and the suggested fixes are to close old tabs or restart Chrome.

    Both fixes throw work away. A closed tab is a source the agent can no longer go back to. A restarted Chrome has lost the agent's logins. We wanted to know whether a browser could keep every tab the agent opened and still use little memory, and whether the agent would notice.

    02What we built and what we compared

    Browserheap keeps the 2 tabs the agent used most recently as live Chromium pages. Every other tab sleeps: its page is closed and the tab keeps its URL, title, scroll position and visible text. The agent can still read a sleeping tab. When it clicks, types or reads from the live page, the tab wakes and comes back where it was, with the same cookies. Tabs holding text the agent typed but hasn't sent never sleep.

    The agent never sees any of this. Its code holds pages and locators that belong to the tab, not to a Chromium page, so a page kept in a variable still works after its tab slept and woke.

    We compared it with the agent tools people use today, each with its default settings: agent-browser, Stagehand, browser-use and Playwright MCP, plus plain headless Chrome. All five run Chrome underneath. We also included two browser engines built to be light: Lightpanda, which doesn't lay out or draw pages, and Obscura.

    03Memory, 1 to 30 tabs

    Each browser opened the same 30 real websites one after another, from Wikipedia and MDN to The Verge, Bloomberg and Amazon, and never closed any. After each page loaded we summed the memory of every browser process.

    • Browserheap
    • agent tools (Chrome underneath)
    • browser engines
    Figure 1. Memory of all browser processes (Linux PSS) after each tab loads. Hover for every browser's number at each tab.

    At 30 tabs, after a 5 s settle

    Memory added by each extra tab

    Figure 2. Left: total memory with all 30 tabs open. Right: the slope of a straight line through each run, which is what one more tab costs.

    Lightpanda is the interesting case. It starts lighter than Browserheap, because it never draws a page, and it stays lighter for the first 10 or so tabs. But each of its tabs stays in memory, and on heavy news sites like Wired and Bloomberg it grows by about 1 GB at a time. By 30 tabs it uses more memory than headless Chrome.

    274ms

    The cost of sleeping: waking the first tab again after all 30 were open, from the agent's click to the page being ready to use.

    Past 30 tabs

    Thirty tabs is a long research task. Agents that run for hours open more. We kept going to 100 tabs, opening the same 30 sites again from the top, and stopped each browser once it used 6.5 GB of the sandbox's 8 GB, or when it crashed.

    Figure 3. Memory up to 100 tabs. × marks where a browser hit the 6.5 GB limit and we stopped it.

    While the agent does something else

    Open tabs don't sit still. News sites refresh, ads rotate, videos autoplay and analytics scripts keep reporting. After the 30 tabs were open we left each browser alone for 10 minutes and sampled its memory and CPU every 15 seconds. This is what idle tabs cost while the agent is thinking, or waiting on a model.

    CPU, % of one core

    Memory

    Figure 4. 30 tabs open, nothing happening, sampled every 15 s for 10 minutes. 100% is one full CPU core.

    How many tabs to keep live

    Two live tabs is the default because an agent usually works in one page and glances at another. An agent that switches between more pages can keep more awake. This is what that costs at 30 tabs.

    Figure 5. Browserheap with 30 tabs open and 1, 2, 4 or 8 of them live, against headless Chrome with all 30 live.

    04Many agents, one machine

    Memory per tab decides how many agents fit on a machine. We started 10 agents on one sandbox, each with its own browser, and had them open tabs at the same time, one round at a time, up to 10 tabs each. Each agent read different sites.

    Figure 6. All 10 browsers together, after each round. The dashed line is the 6.5 GB limit where we stop.

    05Can an agent still work in it?

    Low memory is easy if you give up on parts of the web. We wrote 19 tests for the things agents actually do, from clicking a button to clicking inside an iframe from another site, reading a web component and taking a screenshot. Each ran through Playwright on a small test site, in a fresh browser, with no AI model involved.

    Table 1. Every agent tool runs Chrome underneath, so the Chrome column is theirs as well.

    Browserheap passed all 19, like Chrome, because it is Chrome. Lightpanda failed 7: iframes, web components, element positions, clicking at a position, scrolling to load more, popups and screenshots. Several of those follow from not drawing pages. Its screenshot returns text, so we check the colour of a pixel rather than trusting that a file came back.

    What waking costs

    Every time the agent goes back to a sleeping tab, it waits for that tab to wake. With all 30 tabs open, we woke each one in turn and timed it, and compared that with how long the same page took to load the first time.

    Figure 7. Each dot is one tab; the black tick is the median. Log scale. Hover a dot for its site.

    06Do real sites work?

    We loaded 60 real sites across 6 kinds (docs, news, shopping, code and forums, web apps and plain information pages) one at a time. A page counts as the same content as Chrome's when it shows at least 60% of the distinct words Chrome's page shows, counted only where Chrome loaded the page.

    Table 2. Load time is until the page is usable. Pages behind a bot wall count as not loaded.
    Figure 8. Load time of every site that loaded, one dot per site, log scale. The black tick is the median.
    Table 3. Sites that loaded, by kind of site.

    Browserheap loads faster than plain Chrome because it blocks ads and trackers. Its one page that differs from Chrome is Twitch, whose live listing changes between visits. Lightpanda got past bot walls that stop headless Chrome on CNN, Best Buy, Zara and Spotify, which is a real advantage. Obscura timed out or showed nothing on The Verge, Walmart, Target, Al Jazeera and the Apple Store.

    07Does sleeping hurt the agent?

    The tests above don't use a model. The question that matters is whether an agent doing real work does worse when most of its tabs are asleep. We ran tasks from BU Bench V1 with the same agent, the same model and the same settings on two browsers: plain headless Chrome with every tab live, and Browserheap. The agent is a pi agent with one browser tool that runs JavaScript against the pages.

    Table 4. 10 tasks, 2 from each of BU Bench's 5 categories, 5 running at once. Each answer graded by the benchmark's own grader.
    Table 5. Tasks solved by category. "Impossible" is the grader's verdict for tasks it judged couldn't be done as written.
    • Browserheap
    • headless Chrome
    • filled: solved · ring: not solved
    Figure 9. Each BU Bench task, how long the agent took on each browser.

    Ten tasks is a first look, not a score. We are running the full 100 tasks next, on E2B, and will publish every per-task result. We're not publishing task text, since the benchmark's tasks are meant to stay out of training data.

    08Configuration

    09Limits and fairness

    • One run per test. A first memory run a few minutes earlier gave Browserheap 556 MB and the other agent tools 3.5 to 4.5 GB. We'll repeat runs and publish medians.
    • The sandboxes run as root, where Chrome only starts without its own sandbox. agent-browser, Stagehand and Playwright turn it off themselves; Playwright MCP and browser-use got their own flag for it.
    • Lightpanda holds one page per connection, so each of its tabs had its own connection, and its tabs didn't share cookies. Obscura needed its flag to reach the local test site.
    • The tools' own processes are left out. We count only browser processes, not the Node or Python process driving them. That favours the others.
    • Ads and trackers are blocked in Browserheap and not in the others, which run with defaults. Blocking makes each live page lighter too, so part of the gap per live page comes from it. The growth with tab count does not: Browserheap never has more than 2 live pages.
    • Refs from a snapshot don't survive a wake. An agent that saved a ref like e12 must take a new snapshot after the tab wakes. Role, text and CSS locators keep working.
    • The later runs hit sites from up to 20 sandboxes at once. Some sites blocked more often in those runs, so their "pages that loaded" counts are a little lower than in the first memory run. A blocked page still counts as an open tab.
    • Waking was timed on the Browserheap side only. The first-load times next to it come from the same run, so both include the same network.
    • The agent tasks ran on a MacBook, through the browser running locally, not on E2B. The full run will be on E2B.

    10Raw data and how to reproduce

    Every result file is in the repository under bench/launch/2026-10-15/. The BU Bench file keeps each task's category, verdict, steps and time, without the task itself.

    Every memory number, all 8 browsers, all 30 tabs
    † that browser's page showed a bot wall or didn't load. It still counts as an open tab.
    # one E2B sandbox per job; needs E2B_API_KEY
    node bench/e2b/run.ts memory 30
    node bench/e2b/run.ts actions
    node bench/e2b/run.ts compat