Proxies for Playwright: The Right Type, Setup, and Avoiding Bans

Proxies for Playwright: which type fits, native auth setup in Python and Node, per-context IPs, sticky vs rotating, and how to keep from getting banned.

HProxy Team 10 min read
Proxy.Use case

Free proxies won't hold up here.

Shared datacenter IPs get flagged and dropped fast. When it has to hold, gaming, streaming, accounts, you need mobile and residential IPs that read as a real device, from $0.65/GB, pay as you go.

See plans & pricing

If you are driving a real browser with Playwright and running into rate limits, geo-walls, or outright blocks, proxies for Playwright are how you spread that traffic across many IPs instead of hammering a target from one. Playwright happens to have the cleanest proxy support of any major automation tool: it takes a username and password natively, it can run a different IP per browser context, and because it drives a genuine browser engine it clears the hardest anti-bot layers for free.

This guide covers the parts that actually decide success: which proxy type fits Playwright and why, the honest free-versus-paid picture, the exact setup in Python and Node, the per-context trick that lets one browser wear many IPs, and how to keep your automation from getting banned once the proxy is in place.

Why use proxies with Playwright?

People reach for Playwright when a plain HTTP request will not do: the page renders with JavaScript, sets cookies through a flow, or sits behind a bot defense that expects a real browser. That means by the time you want proxies for Playwright, you are usually already on a target that watches IPs closely.

A browser fired from one address, requesting page after page faster than any person browses, trips the same escalation every scraper meets: rate limiting first (a 429 or a slowdown), then an outright IP block, then fingerprint-level scrutiny that serves CAPTCHAs or fake data. Proxies handle the first two by spreading requests across many IPs, so no single address piles up enough activity to look wrong. There is a Playwright-specific reason to care more than a requests-based scraper would: every Playwright session is heavy and stateful. A dead or blocked exit does not cost you one cheap retry, it throws away a whole browser context (its cookies, its login, the seconds you spent loading pages). The price of a bad IP is higher here, not lower.

Geo-testing is the other big driver. If you need to see a site, a price, or an ad exactly as a user in Berlin or Sao Paulo would, you route that context through an IP in that country and Playwright renders the local reality.

Which proxy type fits Playwright?

Match the proxy to the target, not to a spec sheet. Since Playwright is usually the tool you escalate to for defended sites, residential is the default answer, but not always.

Residential proxies. IPs on real home connections, the kind an ordinary visitor uses. To a website they read as a normal consumer, so they clear the reputation checks that reject hosting IPs on sight. This is the right match for the exact targets that pushed you to Playwright in the first place: retailers, search, social, travel, anything with a real bot team. If you are unsure what these are, what a residential proxy is explains the mechanics. The tradeoff is cost (metered per gigabyte) and some per-exit speed variance, since real home lines are not datacenter-fast.

Datacenter proxies. IPs from hosting providers. Fast, cheap, plentiful, and honest to a fault: a site can tell the IP belongs to a datacenter, so defended targets distrust them. Their place in Playwright work is real though: QA-testing your own app from another region, hitting internal or lightly-defended pages, and any job where the target does not scrutinize IP reputation. Start here whenever the target allows it, because it is the cheapest tier.

Static residential / ISP proxies. Residential-looking but stable, holding one IP for as long as you want. Their Playwright niche is account-bound automation: anything that logs in and has to stay logged in as one consistent identity, where a mid-session IP change would look like a hijack and break the session.

Mobile proxies. IPs from cellular carriers, shared across many real subscribers through carrier NAT. Blocking one risks blocking hundreds of innocent users, so sites almost never do, which makes mobile the heavyweight for the most hostile targets, at the highest price. Overkill for ordinary work, sometimes the only thing that loads the page at all.

Playwright jobStart withEscalate to
Testing your own app across regionsDatacenterResidential
Lightly defended or internal pagesDatacenterRotating residential
Retail, search, social, travel scrapingRotating residentialMobile
Logged-in, single-identity automationStatic residential / ISPMobile (rarely)
The most bot-hostile sites aliveMobileRethink the approach

The rule inside that table: use the cheapest tier the target tolerates, and move up only when block rates prove you have to. Reaching for mobile on a site that would have accepted residential just burns money.

The honest free-versus-paid reality

Free proxies and Playwright are a bad marriage for production, and it helps to know exactly why. Most free proxies are datacenter IPs that die within minutes, and only a small fraction of any public list is alive at once. Our own free proxy list re-checks and refreshes every few minutes across 100+ countries and HTTP, HTTPS, SOCKS4 and SOCKS5, precisely because the underlying pool churns that fast.

For a requests-based scraper, a dead free proxy is a cheap retry. For Playwright it is expensive: an exit that dies halfway through a flow wastes the whole browser session you built. Stack that on top of the fact that free datacenter IPs are exactly the addresses a defended target already distrusts, and you get the worst case: you spun up a real browser to look human, then wore an IP that screams bot. The one strength Playwright gives you (a genuine browser fingerprint) is thrown away by the weakest possible IP.

Where free is genuinely useful is learning and testing. Wire up your proxy code against the free list, confirm the exit IP changes, test your own app from a few countries, and get the setup right without spending a cent. When you move to real defended targets, paid residential is the honest tool: ours is pay-as-you-go from $0.99/GB with no KYC, so a paused project does not torch a prepaid plan.

How to set up a proxy in Playwright

Here is where Playwright is genuinely nicer than Selenium. You set the proxy at launch, and unlike Chrome's --proxy-server flag, Playwright's proxy object accepts a username and password directly. No local helper, no injected dependency, no native login dialog that hangs your script.

Python:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server": "http://203.0.113.10:8080",
            "username": "user",     # accepted natively, no workaround needed
            "password": "pass",
        }
    )
    page = browser.new_page()
    page.goto("https://httpbin.org/ip")   # shows the exit IP the site sees
    print(page.content())
    browser.close()

Node:

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({
    proxy: {
      server: 'http://203.0.113.10:8080',
      username: 'user',
      password: 'pass',
      // bypass: 'localhost, *.internal.example',  // hosts to skip
    },
  });
  const page = await browser.newPage();
  await page.goto('https://httpbin.org/ip');
  console.log(await page.content());
  await browser.close();
})();

Two honest caveats. First, for a SOCKS5 proxy you change the scheme to socks5://, but the browser engines Playwright drives do not support SOCKS proxies that require a username and password. If you need SOCKS5, authenticate that endpoint by allowlisting your machine's IP with the provider instead. Second, if your provider authenticates by IP allowlist rather than credentials, drop the username and password entirely and the same code works with just server.

One browser, many IPs: per-context proxies

This is Playwright's standout feature for proxy work. A browser context is an isolated session (its own cookies, cache and storage), and you can give each context its own proxy. That means one running browser can hold several independent identities, each on a different IP, at the same time. Selenium cannot do this without launching a separate browser per proxy.

browser = p.chromium.launch(proxy={"server": "per-context"})  # placeholder, see note

ctx_de = browser.new_context(
    proxy={"server": "http://203.0.113.10:8080", "username": "u", "password": "p"}
)
ctx_us = browser.new_context(
    proxy={"server": "http://198.51.100.42:8080", "username": "u", "password": "p"}
)

page_de = ctx_de.new_page()   # one exit
page_us = ctx_us.new_page()   # a different exit, same browser

The one gotcha worth knowing: with Chromium you have to pass a proxy at launch for per-context proxies to take effect, even a placeholder like {"server": "per-context"}. Set that once and every context's own proxy is honored. Firefox and WebKit do not need the placeholder. This trades cleanly against process weight: contexts are far lighter than whole browsers, so many identities per browser is how you get concurrency out of Playwright without your RAM disappearing.

Sticky vs rotating: match the IP to the flow

The instinct carried over from HTTP scraping is to rotate the IP on every request. For Playwright that instinct is usually wrong, because Playwright work is stateful. A context logs in, sets cookies, paginates, adds to a cart. If the exit IP changed underneath that flow, the site would see one session teleport between addresses mid-visit, which reads as account theft, not a shopper. So the default for Playwright is a sticky IP: one exit held for the life of the context.

You still rotate, just at the right seam. Rotate between contexts and between runs, not within a single flow. Give each context a fresh sticky IP, do the whole logical journey on it, tear the context down, and let the next one draw a new IP. If you are choosing between a rotating pool and pinned static IPs, rotating vs static residential walks through when each wins. For most Playwright scraping, rotating residential with a sticky window per context is the sweet spot.

One thing not to break: geographic consistency. A session whose IP jumps from Germany to Brazil to Japan across three clicks has described itself as a bot in one sentence. Pin a country per context and keep it there for the whole flow.

How many IPs do you actually need? Fewer than an HTTP scraper, because Playwright's concurrency ceiling is lower: each context costs real memory and CPU, so you run tens of them, not thousands. That maps perfectly onto a rotating residential gateway, a single host and port that hands out a fresh sticky exit per context. You point every context at the same endpoint and the pool does the rotating, so there is no IP list to manage in your code.

Avoiding blocks: a proxy fixes the IP, not the fingerprint

This is the part worth being blunt about. A proxy changes the address a site sees. It does nothing about the many other signals that give automation away, and Playwright ships some of those signals by default.

The good news first: because Playwright drives a real browser engine, it wins the hardest layers for free. Its TLS and HTTP/2 handshake genuinely is Chromium's, Firefox's or WebKit's, so the fingerprinting that instantly catches a raw HTTP client does not catch Playwright. That is a real advantage over a requests-based scraper and half the reason you chose it.

The bad news: Playwright-driven Chromium still exposes automation tells at the JavaScript layer, including navigator.webdriver and artifacts of the DevTools connection it runs on, and it moves with a mechanical precision no hand produces. A serious anti-bot system reads all of that no matter how clean your exit IP is. We wrote the full breakdown from the defender's seat in how websites detect proxies: the ASN behind the IP, header order, request pacing, and DNS or WebRTC leaks. Stealth patches such as playwright-stealth and the rebrowser project hide some of the JavaScript flags, and human-like pacing (real delays, randomized, with pauses between logical steps) handles the behavior, but no proxy and no patch makes a bot invisible on a site that truly cares.

One combination to avoid: headless plus a fresh unknown IP. Headless browsers leak automation tells that a normal window does not, and pairing an obviously-automated headless fingerprint with a brand-new residential IP is one of the most suspicious profiles you can present. If a target is genuinely defended, a headed Playwright session on a good residential IP is far less conspicuous than a headless one.

Where to point Playwright

For anything facing real defenses, the exit IP decides the most, so start there. Our residential proxies route through real consumer connections and rotate from a single gateway, which is exactly the shape Playwright wants: one host and port in your proxy object, a fresh believable IP per context, sticky for the length of a flow, and no rotation code to maintain.

Before you trust any exit in a run, confirm what it looks like from outside. Drop it into our proxy checker to read its real exit IP, anonymity grade and speed, and if you want the method behind that, how to check if a proxy is working covers it. Start on the free proxy list to get your Playwright wiring right for nothing, then move to residential at $0.99/GB pay-as-you-go (no KYC) when you point it at targets that bite back. Get the IP right and the proxy side of Playwright stops being the hard part, which frees you to write the automation you actually came to build.

Frequently asked questions

How do I set a proxy in Playwright?

Set it at launch through the proxy option. Pass an object with a server field, for example chromium.launch(proxy={'server': 'http://IP:PORT'}). Playwright also accepts username and password in that same object, so authenticated proxies work natively without any helper library. The proxy then applies to the whole browser, or you can set a per-context proxy instead to give each context its own IP.

Does Playwright support username and password proxy authentication?

Yes, natively. Unlike Selenium with Chrome's --proxy-server flag, which ignores credentials and pops a login dialog that hangs the script, Playwright's proxy object takes username and password fields directly and handles the authentication for you. The one exception is SOCKS5: the underlying browser engines do not support SOCKS proxies that require a username and password, so authenticate a SOCKS5 endpoint by IP allowlist instead.

What kind of proxy is best for Playwright?

For the defended sites that usually push people to Playwright (retail, search, social, travel), rotating residential proxies are the right match, because they read as ordinary home users and clear reputation checks that reject datacenter IPs. Datacenter proxies are fine and cheaper for testing your own app across regions or hitting lightly defended pages. Mobile is the heavyweight for the most hostile targets, and static residential or ISP proxies suit logged-in, single-identity automation.

Can I use a different proxy for each browser context in Playwright?

Yes, and it is one of Playwright's best features. Each browser context is isolated (its own cookies and storage) and can take its own proxy, so one running browser can hold several identities on different IPs at once. With Chromium you must pass a placeholder proxy at launch (such as server: 'per-context') for context-level proxies to take effect. Firefox and WebKit do not need it.

Does a proxy stop a Playwright bot from being detected?

No. A proxy only changes the IP a site sees. Playwright still exposes automation signals such as navigator.webdriver and drives a real engine with mechanical timing, so a serious anti-bot system can flag it regardless of IP. Playwright's advantage is that its TLS and HTTP/2 fingerprint is a genuine browser's, which defeats the layer that catches raw HTTP clients. Combine a clean residential IP, stealth patches and human-like pacing for the best odds.

HProxy Team
We run a proxy network

Keep reading

Proxies that don't die mid-job

Residential, ISP, datacenter and mobile, verified by the same engine that runs tens of millions of checks. They read as a real device and hold up under load. Pay as you go, and your balance never expires.

47M+ proxy checks run · 100+ countries · HTTP / HTTPS / SOCKS · re-checked every few minutes · no signup