Browser Execution and Pooling
packages/browser keeps a process-level pool of Chromium browsers, keyed by launch profile — the sorted launch args, headless, channel, executablePath, and any launch-level proxy server, hashed together. getOrCreateBrowser(launchOptions) returns the pooled browser for that exact profile, launching a new one only when no match exists.
This reconciles two goals that pull in opposite directions:
- Memory conservation, by default. Most runs share one browser process and each gets a fresh, isolated
BrowserContext— separate cookies, storage, cache, proxy, user agent, viewport, locale, and timezone. That is enough isolation for the common case cheaply. - Process-level fingerprint isolation, on demand. Some signals are fixed for an entire Chromium process — launch flags, the TLS/JA3 stack, GPU/WebGL, HTTP/2 framing — and cannot differ between two contexts of the same browser. A Challenger extension that needs traffic to look like a genuinely different machine sets distinct
launchArgs(and optionally a launch-level proxy) viactx.helpers.patchContextOptions(...)duringbootstrap-context; the pool then hands that run its own browser process. Identical profiles keep sharing one process; distinct ones don't.
launchArgs from an extension are always merged on top of the hardening defaults, never replace them.
Pool bounds
The pool is bounded by BROWSER_POOL_MAX (default 4) and evicts the least-recently-used browser that currently has no open contexts when the bound is reached — an active run is never torn down out from under it.
Next steps
- The Challenger Framework for where
bootstrap-contextsits in the overall run lifecycle. - Environment Variables reference for
BROWSER_POOL_MAXand related tuning.