Headless Browser Resource Usage Across Many Sessions
Short answer
How much do Selenium and Playwright sessions cost in resources, and how do you run many?
Each full browser instance typically needs 150-500 MB of RAM, plus CPU spikes during rendering. Playwright browser contexts share one browser process, so many isolated sessions cost far less than many browsers. Block images, fonts and media, cap concurrency to available memory and recycle browsers periodically. AlterLab runs this browser fleet for you.
Step by step
- 1
Prefer contexts over browsers
Open one browser per worker and a new context per session. Contexts isolate cookies and storage at a fraction of the memory cost.
- 2
Block heavy resources
Abort requests for images, media and fonts you do not need. This cuts both memory and bandwidth.
- 3
Cap concurrency by memory
Set the number of parallel sessions from measured memory per session, not CPU count, and leave headroom.
- 4
Recycle regularly
Restart each browser after a few hundred pages to release leaked memory.
Example
from playwright.async_api import async_playwright
async def run(urls: list[str]) -> None:
async with async_playwright() as p:
browser = await p.chromium.launch()
for url in urls:
context = await browser.new_context() # cheap, isolated session
page = await context.new_page()
await page.route("**/*.{png,jpg,jpeg,gif,woff,woff2,mp4}",
lambda route: route.abort())
await page.goto(url)
print(await page.title())
await context.close()
await browser.close()Frequently Asked Questions
Is Selenium heavier than Playwright?
Per browser they are similar, since both drive the same engines. Playwright's lightweight contexts make many parallel sessions cheaper than one Selenium driver per session.
When should I stop managing browsers myself?
When fleet size, crashes and memory tuning take more time than your extraction logic. A rendering API removes the fleet entirely and bills per page.
Read the full guide
How to handle JavaScript-rendered pagesTry it with AlterLab
Send a URL, get the page back as HTML, markdown or JSON. Rendering, proxy rotation and retries are handled for you.
Your first scrape.
Sixty seconds.
Up to 5,000 free requests — about 5,000 Light, 500 Protected or 250 Dynamic requests. No credit card.
Just a POST request.
No credit card required · Up to 5,000 free requests (about 5,000 Light, 500 Protected or 250 Dynamic requests) · Balance never expires