Playwright takes a proxy in two places: once for the whole browser at launch, or separately for each browser context. Its proxy object accepts a username and password for HTTP proxies, so authenticated proxies need no helper. SOCKS5 works only without a login. The proxy type matters more than the code. In our price records for July to October 2026, the median smallest residential plan cost $3.38 per GB, against $0.60 for datacenter. This guide covers the setup in Python and Node, one IP per context and the SOCKS5 limit. It also covers installs behind a proxy, which type fits which job, and what a proxy cannot hide.
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. So by the time you add proxies, you are usually on a target that watches IPs closely.
A browser that requests page after page from one address, faster than any person, meets the usual escalation. First comes a rate limit, a 429 or a slowdown, then an IP block, then fingerprint checks that serve CAPTCHAs or fake data. Proxies handle the first two by spreading requests over many IPs.
One IP, many pages
faster than a person
Rate limit
429 or a slowdown
IP block
address cut off
CAPTCHA / fake data
fingerprint scrutiny
A bad IP costs more in Playwright than in a requests-based scraper. Each session is heavy and keeps state. A blocked exit throws away a whole browser context, with its cookies, its login and the seconds spent loading pages. Geo-testing is the other big reason. Route a context through an IP in Berlin or Sao Paulo, and Playwright renders the page as a local visitor sees it.
How do you set a proxy in Playwright?
Set it at launch. Playwright's network docs say: "You can configure pages to load over the HTTP(S) proxy or SOCKSv5". The proxy object takes server, username, password and bypass.
Python:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": "http://HOST:PORT",
"username": "YOUR-LOGIN", # for HTTP proxies, accepted natively
"password": "YOUR-PASSWORD",
}
)
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://HOST:PORT',
username: 'YOUR-LOGIN',
password: 'YOUR-PASSWORD',
// 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();
})();
If your provider authenticates by an IP allowlist instead of a login, drop username and password and keep server. Check the exit from inside the browser, as above. A Python or Node request outside the browser does not tell you what the page used.
How do you give each browser context its own IP?
A browser context is an isolated session with its own cookies, cache and storage, and each one can take its own proxy. One running browser can then hold several identities on different IPs at once. Selenium needs a separate browser per proxy for that. Puppeteer manages it through its own browser contexts.
browser = p.chromium.launch()
ctx_de = browser.new_context(
proxy={"server": "http://HOST-1:PORT", "username": "YOUR-LOGIN", "password": "YOUR-PASSWORD"}
)
ctx_us = browser.new_context(
proxy={"server": "http://HOST-2:PORT", "username": "YOUR-LOGIN", "password": "YOUR-PASSWORD"}
)
page_de = ctx_de.new_page() # one exit
page_us = ctx_us.new_page() # a different exit, same browser
The current docs launch Chromium with no global proxy and set the proxy per context. Many guides still pass a placeholder at launch, such as {"server": "per-context"}, from older versions that needed it on Chromium. If your version refuses a context proxy, add that placeholder. Contexts are far lighter than whole browsers, so many identities per browser is how you get concurrency without running out of memory.
Can Playwright use a SOCKS5 proxy with a login?
No. Playwright's API describes username and password as for when an "HTTP proxy requires authentication". Chromium's own documentation states: "No authentication methods are supported for SOCKSv5 in Chrome". We saw the same in our SOCKS5 tests. Headless Chrome 155 offered only the no-login method, and a proxy that required a login turned it away.
So with Playwright, use SOCKS5 only on an endpoint that authenticates your IP by allowlist. Otherwise use the provider's HTTP endpoint with a login. In Chrome, SOCKS5 also carries TCP only: Chromium notes it "cannot be used to relay UDP traffic".
How do you install Playwright behind a corporate proxy?
That is a separate proxy: the one your company uses to reach the internet, rather than the exit your scraper uses. Playwright downloads its browsers from Microsoft's CDN, and its docs show how to send that download through a proxy server:
HTTPS_PROXY=https://PROXY-HOST:PORT npx playwright install
If the corporate proxy re-signs traffic with its own certificate authority, the install fails with a self-signed certificate error. The docs point NODE_EXTRA_CA_CERTS at that certificate. On Linux, run install-deps as root with the variable set, or the package manager will not see it.
Which proxy type fits Playwright?
Match the proxy to the target. Playwright is usually the tool you escalate to for defended sites, so residential is the common answer. Often a cheaper type does the job, though.
Residential proxies
Addresses on home connections, the kind an ordinary visitor uses. Sites read them as normal consumers, so they pass the reputation checks that reject hosting addresses. They match the targets that push people to Playwright: retailers, search, social and travel. What a residential proxy is explains the mechanics. They cost the most per GB after mobile, and home lines vary in speed.
Datacenter proxies
Addresses from hosting providers: fast, cheap and easy to recognize as servers, so defended targets distrust them. They fit testing your own app from another region, internal or lightly defended pages, and any target that ignores IP reputation. Start here whenever the target allows it.
Static residential and ISP proxies
Addresses that look residential and stay the same for as long as you rent them. They fit logged-in automation that has to stay one identity, where a change of IP mid-session would look like a hijack.
Mobile proxies
Addresses from cellular carriers, shared by many real subscribers through carrier NAT. Blocking one risks blocking many people, so sites rarely do. They are the most expensive type and usually more than a job needs.
- Smallest plan
- Largest plan
| Playwright job | Start with | Move up to |
|---|---|---|
| Testing your own app by region | Datacenter | Residential |
| Lightly defended or internal pages | Datacenter | Residential |
| Retail, search, social, travel | Residential | Mobile |
| Logged-in, single identity | Static ISP | Mobile |
Use the cheapest type the target tolerates, and move up only when block rates force you to. Mobile on a site that accepts residential costs about a fifth more per GB on the smallest plans, for nothing.
Are free proxies good enough for Playwright?
For learning and tests, yes. For production, rarely. Free proxies churn fast: of 12,477 free proxies that answered our checker on October 17, 2026, half did not answer a day later. Only 3,463, or 27.8%, answered on all five following days. Our free proxy list re-checks its entries around the clock for that reason.
A dead free proxy is a cheap retry for a requests-based scraper. For Playwright it costs a whole browser session. Free proxies are also mostly server addresses that defended sites already distrust. A real browser fingerprint then ends up wearing the weakest kind of IP. Use the free list to wire up your proxy code and confirm the exit changes, then switch to a paid pool for defended targets.
Sticky or rotating IPs for Playwright?
Usually sticky within a flow. Playwright work keeps state: a context logs in, sets cookies, pages through results and fills a cart. If the exit IP changed during that flow, the site would see one session jump between addresses, which looks like account theft. So hold one exit for the life of a context.
Rotate at the right seam: between contexts and between runs. Give each context a fresh sticky IP and run the whole journey on it. Then close the context and let the next one draw a new IP. Rotating vs static residential covers when a fixed address wins instead.
Keep the country fixed too. A session whose IP moves from Germany to Brazil to Japan across three clicks describes itself as a bot. And you need fewer IPs than an HTTP scraper does, because each context costs real memory and CPU. A rotating gateway fits that shape well: one host and port in your proxy object, and a fresh sticky exit per context.
Does a proxy stop Playwright from being detected?
A proxy changes the IP and nothing else. The other signals stay where they are, and automated Chrome sends some by default. MDN documents that navigator.webdriver is true in Chrome when the "--enable-automation or --headless flag is used". Movement and timing can look mechanical too. How websites detect proxies walks through the checks a defended site runs. Stealth plugins such as playwright-stealth hide some of the JavaScript signs, and human-like pacing helps with behavior. Neither makes automation invisible to a site that truly cares.
Playwright's strength sits one layer down. It drives a real browser engine, so its TLS handshake comes from the browser's own TLS stack. That beats the checks that catch raw HTTP clients. In our JA3 and JA4 capture, headless Chrome 155 sent the same cipher part as the Chrome fingerprint FoxIO published in 2023.
Avoid one combination: headless mode on a fresh, unknown IP. Headless browsers carry automation signs that a normal window does not, and the pair looks suspicious. On a truly defended target, a headed session on a good residential IP draws less attention.
Where to point Playwright
For anything facing real defenses, start with the exit IP. Our residential proxies rotate behind one gateway, which suits Playwright. You put one host and port in the proxy object and get a sticky exit per context. Residential Lite costs $0.50 per GB, falling to $0.44/GB at 2,000 GB+, and comes as HTTP or SOCKS5 lines. For Playwright, use the HTTP lines with a login, since Chromium cannot log in to a SOCKS5 proxy.
Before you trust an exit, check it from outside. Our proxy checker shows a proxy's exit IP, anonymity grade and speed. How to check if a proxy is working explains the method. To order IPs from code before the browser starts, the HProxy API docs cover plans and delivery over REST.
What this page could not check
- No Playwright test of our own. The setup facts come from Playwright's documentation of October 22, 2026, and from our own Chrome tests. We did not run Playwright itself.
- Version differences. Older Playwright versions behaved differently on per-context proxies. Check the docs for your version.
- Prices move. The medians come from seller pages captured between July 20 and October 22, 2026. They use each seller's listed plans and leave out headline "from" prices. Sellers change plans often.
- Free list only. The survival numbers cover public free proxies our checker collects.
- Check by January 22, 2027.
Sources
- Playwright docs, Network: HTTP Proxy, read October 22, 2026.
- Playwright API, BrowserType.launch proxy option, and Browser.newContext proxy option, read October 22, 2026.
- Playwright docs, Browsers: install behind a firewall or a proxy, read October 22, 2026.
- Proxy support in Chrome (net/docs/proxy.md). Chromium source, read October 22, 2026.
- Navigator: webdriver property. MDN Web Docs, read October 22, 2026.
- HProxy price records: median per-GB prices by proxy type, 68 sellers, captured July 20 to October 22, 2026.
- HProxy free proxy list: survival of the October 17, 2026 cohort, checked through October 22, 2026.



