BLOG
Browser Use Free: What You Actually Get and When to Move
Browser use free tiers are fine for prototypes. Learn what free browser use covers, where it breaks, and how to run production agents on hosted Chromium.
# Browser Use Free: What You Actually Get and When to Move
"Browser use free" usually means one of two things: you want to run browser-use agents without paying for a hosted runtime, or you want to know whether a free tier is enough before you commit engineering time. Both questions have the same answer — free is a valid starting point, but the constraints show up fast once your agent has to run on a schedule, behind a login, or against a site that blocks datacenter IPs.
This guide covers what free browser use realistically includes, the specific failure modes you hit at each stage, and how to move a working prototype onto hosted Chromium without rewriting your agent. If you already know you need a runtime, start with Remote Browser for AI agents and come back here for the migration details.
What "free" means in browser use
There are three distinct things people call free browser use, and they have very different cost profiles:
- Local Chromium on your own machine. Playwright, Puppeteer, or browser-use driving a browser you installed. No vendor bill, but you pay in setup time, RAM, and the fact that it only runs when your laptop is open.
- Free tiers on hosted browser platforms. A metered allowance of browser-hours or sessions. Useful for evaluation, but the limits are usually low enough that a single agent loop can exhaust them.
- Free open-source frameworks. browser-use itself, Playwright, Puppeteer, Selenium. The library is free; the infrastructure it needs is not.
The confusion is that these get marketed interchangeably. A free framework plus a free tier is not the same as a free production runtime. The framework is the part that decides *what* to click. The runtime is the part that keeps a browser alive, reachable, and unblocked while the agent works.
For a prototype, local Chromium is genuinely fine. You install Playwright, run playwright install chromium, and you have a browser in under two minutes. The problems start when the agent needs to run more than once.
Where free browser use breaks
The failure modes are predictable. They show up in roughly this order as your agent matures.
1. Session lifetime
A local browser dies when your process exits. If your agent needs to log in once and then act over hours or days, you need a persistent profile — cookies, localStorage, and session state that survive restarts. Local Chromium can do this with a user data directory, but only on the machine that holds it. The moment you move to a container, a CI runner, or a second worker, the profile is gone.
Hosted runtimes solve this with persistent profiles attached to a session ID. You reconnect to the same profile from any worker. See Remote Browser online for how that connection model works.
2. Concurrency and resource limits
One headless Chromium instance is roughly 200–400 MB of RAM at idle, more under load. Five parallel agents on a laptop is already uncomfortable. Twenty is not happening. On a free tier, you are usually capped at one or two concurrent sessions anyway.
3. IP reputation and blocking
This is the one that kills most free setups. Datacenter IPs — including your home ISP if it is flagged, and almost certainly a cloud VM — get challenged by Cloudflare, PerimeterX, and similar. A free tier typically gives you a shared datacenter IP with no proxy configuration. Your agent works on example.com and fails on anything with real bot protection.
You cannot fix this with code. You fix it with residential or mobile proxies, which are not free.
4. Observability
When a local agent fails at step 14 of 30, you get a stack trace and a screenshot if you remembered to take one. You do not get a live view of what the browser was doing, a video, or a DOM snapshot at the moment of failure. Debugging becomes guesswork.
5. Environment drift
Your laptop has fonts, a display server, and a Chromium build that happens to work. A Linux container does not. Headless Chromium in Docker needs specific flags, font packages, and shared memory settings. This is a well-known source of "works on my machine" bugs that have nothing to do with your agent logic.
Free vs hosted: a production comparison
| Criterion | Local / free tier | Hosted Chromium runtime |
|---|---|---|
| Setup time | Minutes for one machine | Minutes, then reusable everywhere |
| Persistent profiles | Tied to one filesystem | Attached to session ID, reachable from any worker |
| Concurrency | 1–2 sessions on a free tier | Configurable, metered per browser-hour |
| Proxy / IP control | Usually none on free | Configurable proxy and browser settings |
| Live debugging | Screenshots you remember to take | Live viewer, session replay |
| CI / serverless fit | Poor — needs a long-lived process | Native — connect over CDP from anywhere |
| Cost model | Your hardware and time | Per browser-hour, see /pricing |
The honest read: free wins on the first day. Hosted wins on the thirtieth.
Connecting an agent to a hosted browser
The migration is smaller than most people expect, because the connection layer is standard. Hosted Chromium exposes a CDP endpoint. Playwright's connectOverCDP attaches to it. Your agent code — the part that decides what to do — does not change.
import { chromium, Browser, Page } from 'playwright';
// The endpoint comes from your runtime's session API.
// Never hardcode it; fetch it per session and treat it as a secret.
async function connectToHostedBrowser(cdpUrl: string): Promise<{ browser: Browser; page: Page }> {
const browser = await chromium.connectOverCDP(cdpUrl, {
timeout: 30_000,
});
// A hosted session usually starts with one context already open.
const context = browser.contexts()[0] ?? (await browser.newContext());
const page = context.pages()[0] ?? (await context.newPage());
return { browser, page };
}
async function runAgentTask(cdpUrl: string) {
const { browser, page } = await connectToHostedBrowser(cdpUrl);
try {
await page.goto('https://example.com/dashboard', {
waitUntil: 'domcontentloaded',
timeout: 45_000,
});
// Persistent profile means the session may already be authenticated.
const loggedIn = await page.locator('[data-testid="user-menu"]').isVisible();
if (!loggedIn) {
throw new Error('Session not authenticated — profile may have expired');
}
await page.getByRole('button', { name: 'Export report' }).click();
await page.waitForEvent('download', { timeout: 60_000 });
} finally {
// Disconnect without killing the remote browser if you want to resume later.
await browser.close();
}
}Two details matter here. First, browser.close() on a CDP connection disconnects your client; whether it terminates the remote session depends on the runtime. Check your provider's semantics before assuming either behavior. Second, the persistent profile is what makes the loggedIn check meaningful — without it, every run starts from a login page.
The same endpoint works from Puppeteer (puppeteer.connect({ browserWSEndpoint })) and Selenium (via a CDP bridge). If you are wiring up a specific client, the documentation covers the connection strings for each.
Production criteria that free tiers cannot meet
If you are evaluating whether to move off free, these are the criteria that actually predict whether your agent survives contact with real sites.
Session isolation. Two agents must not share cookies or storage. On a shared free tier, this is often not guaranteed. On a hosted runtime, each session gets its own browser context and profile.
Profile persistence with expiry control. You need to know how long a profile lives, how to rotate it, and how to detect that a login has expired before the agent fails mid-task.
Proxy configuration. Residential and mobile proxies are the difference between a 20% success rate and a usable one on protected sites. This is a paid feature everywhere, including on the platforms that offer generous free tiers.
Observability. A live viewer and session replay turn a 40-minute debugging session into a 2-minute one. This is the feature people underestimate most before they need it.
Usage controls. Per-session timeouts, spend caps, and concurrency limits. Without these, a runaway agent loop is an expensive bug. See /pricing for how metering works on Remote Browser.
Reproducible environments. The Chromium build, fonts, and flags should be identical across every session. This eliminates an entire class of bugs.
Common setup problems and what they mean
A few errors come up repeatedly when people move from local to hosted, or when they try to wire an agent framework to a remote browser.
"Hermes remote browser not working." This usually means the CDP endpoint is reachable but the agent is not attaching to the right context. Hosted sessions often pre-open a context and a page; if your code calls newContext() unconditionally, you get a second blank context and the agent acts on the wrong one. Check browser.contexts() first.
Connection refused or timeout on the CDP URL. The endpoint is per-session and short-lived. If you cached a URL from a previous run, it is dead. Fetch a fresh one per session.
Agent connects but every navigation fails. Almost always a proxy or DNS issue on the runtime side, not your code. Verify the session's network configuration before debugging the agent.
Works locally, fails remotely on the same URL. Environment drift — missing fonts, different viewport, or a headless-specific rendering difference. Set an explicit viewport and user agent rather than relying on defaults.
For a deeper look at driving a remote browser from arbitrary code, see Remote control browser.
When free is still the right call
Do not migrate prematurely. Free browser use is the correct choice when:
- You are still writing the agent's decision logic and the browser is incidental.
- You are testing against sites you control, with no bot protection.
- You run the agent interactively, a few times a day, from one machine.
- You have not yet hit a blocking or concurrency wall.
Move to a hosted runtime when any of these become true: the agent runs on a schedule, it needs to stay logged in, it runs against protected sites, it needs to run in parallel, or you cannot debug it from a stack trace alone.
The framework is free either way. What you are paying for is the browser staying alive, reachable, and unblocked — which is the part that determines whether the agent works in production. Start with the documentation to see the connection model, and check /pricing for current metering before you commit to a migration.
For the broader picture of why this runtime layer exists, Remote web browser covers the architecture.