Build vs buy: what a browser fleet actually costs
The compute bill is the small number. A model for the real cost of running your own browser infrastructure, and the three cases where building wins.
Read the postGive your agents a real browser that logs in to the supplier portals, banks and government sites your business already runs on. Credentials stay in an encrypted vault and never reach the model.
Runs on EU infrastructure and open standards
5 h
Free browser time to start with. No card.
€0.08
Per browser hour, once the free tier runs out.
0
Stealth features. That one is deliberate.
24 h
Default replay retention, then it is deleted.
Sessions speak the Chrome DevTools Protocol, so Playwright, Puppeteer and Selenium work unchanged. You swap the endpoint, not the code around it.
01
One line. Your selectors, your assertions and your error handling all stay exactly as they are.
02
Five browser hours on the free plan, no card, and nothing to install. If it does not work, you have lost ten minutes.
import { chromium } from 'playwright';
const browser = await chromium.connectOverCDP(
`wss://browserberg.com/v1/connect?token=${process.env.BB_TOKEN}`);
const page = await browser.contexts()[0].newPage();
await page.goto('https://portal.example.de');
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(
f"wss://browserberg.com/v1/connect?token={token}")
page = browser.contexts[0].new_page()
page.goto("https://portal.example.de")
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.connect({
browserWSEndpoint: `wss://browserberg.com/v1/connect?token=${process.env.BB_TOKEN}`
});
const [page] = await browser.pages();
await page.goto('https://portal.example.de');
curl -X POST https://browserberg.com/v1/sessions \
-H "Authorization: Bearer $BB_TOKEN" \
-H "Content-Type: application/json" \
-d '{"shape":{"locale":"de-DE","timezone":"Europe/Berlin"}}'
# 201 Created
# { "session": { "id": "sess_...", "connectUrl": "wss://..." } }
Agent demos work beautifully. Then the login wants a second factor, the session drops halfway through, and a password turns up in a transcript. Those are infrastructure problems, and they are the ones we took on.
Rolling your own
On Browserberg
Ask for a browser and get back a URL you can connect to. Locale and timezone are German by default, because that is what the sites you are automating expect to see.
Log in once and keep it. Cookies, local storage and the whole session are encrypted per tenant and restored the next time you start.
Put a placeholder in your script and the vault fills it in on the page itself, only on the site it belongs to. The real secret never enters a prompt, a log or a transcript.
Watch a run live, and step in when the site asks for something an agent cannot do. A single-writer lease means you and the agent are never typing at once.
Describe what you want rather than which div it lives in. Observe the page, act on it, extract structured data — and stop rewriting selectors every time marketing ships.
Two tiers behind one key: Performance for frontier models on EU endpoints with zero retention, Sovereign for European models end to end. Or bring your own key and skip it entirely.
Most of what a business actually needs automated has no API. It has a login, a session that expires, and a form that changes twice a year.
See all use cases
Read new orders, confirm deliveries and upload invoices in the portals your customers insist on. No integration project, no waiting for their IT roadmap.
await page.getByRole('button', { name: 'Bestellung bestätigen' }).click();
Pull statements, reconcile payments and check claim status. The vault handles the password and a person handles the photoTAN, so the run finishes instead of stalling.
await page.fill('#pin', '{{vault:bank-de/pin}}');
File through the portals that never grew an API. Cookie banners get handled, uploads get confirmed, and every step is recorded so you can show what happened.
await page.setInputFiles('#datei', 'rechnung-2026-08.xml');
Keep prices and stock in step across seller dashboards, export orders, answer reviews. The sites change often; a profile that stays signed in means you only fix the step that broke.
await page.getByLabel('Bestand').fill(String(stock));
01
One POST returns a connect URL. Choose the locale, timezone and how long it should live, or take the German defaults.
02
Playwright, Puppeteer, Selenium, our SDKs, or an MCP client from inside your editor. It is the same session either way.
03
Follow the run live, step in when a site asks for something only a person can give, and replay it afterwards.
The compute bill is the small number. A model for the real cost of running your own browser infrastructure, and the three cases where building wins.
Read the post
Region settings answer the easy question. The seven questions a European data protection review actually asks about agents, and why one is usually missed.
Read the post
Agents do not replace RPA, they move where the decisions live. What that changes about cost, testing and governance, and what stays exactly the same.
Read the postFive browser hours, three concurrent sessions, two profiles and one vault credential, with no card. That is enough to connect a real script and see it run against a real site, which is the only test that tells you anything.
No. Sessions speak the Chrome DevTools Protocol, so Playwright, Puppeteer and Selenium connect as they are. The only line that changes is the one that used to launch a local browser.
On our own hardware in the EU. Recordings default to 24 hours and are capped at 72; after that they are deleted. Data residency here is the architecture rather than a region setting on someone else's cloud.
No, and we will not. No proxy rotation, no fingerprint spoofing, no CAPTCHA solving. If you need to hide from Cloudflare, we are not your vendor. If you need auditable automation of accounts you already have, that is exactly what this is for.
You reference a placeholder. The vault resolves it inside the browser, on the site that credential is scoped to, so the value never enters a prompt, a log or a replay. TOTP codes are generated the same way.
The run pauses and you get a live view with a takeover lease. A person completes the photoTAN or TOTP step, hands control back, and the agent carries on from there.
TypeScript and Python SDKs, anything that speaks CDP, and an MCP server so a coding agent can drive a browser directly from your editor.
They are US-operated and increasingly sell evasion. We run in the EU, refuse stealth, and put the work into the things authenticated automation actually needs: a credential vault, profiles that stay signed in, and a human who can step in. We keep an honest comparison of each of them in the library.