Using Proxies with Playwright in 2026: A Setup Guide

Browser automation looks simple until the first block arrives. A script that works perfectly on your own connection can start returning captchas, login challenges, or empty pages when it runs at scale, from a data center, or against a site that watches for automation signals. Playwright is a powerful tool for testing and data collection, but it does not hide your IP address by itself. That part is the proxy's job, and Playwright handles proxies differently from a simple HTTP client such as Python Requests.
This guide explains how to use proxies with Playwright in 2026: which proxy type fits browser automation, how to configure a proxy per browser context, how to handle authentication, how to rotate IPs safely, and how to test that the setup actually works before you rely on it.
Why Browser Automation Needs a Proxy
When you use Requests, every HTTP call goes through the proxy you set on that session. Playwright is different because it launches a real browser. The browser makes its own connections, loads images, stylesheets, scripts, and third-party resources, and may open WebSocket connections. A proxy configured at the browser-context level covers all of that traffic, which is exactly what you want for consistent testing and measurement.
There are several legitimate reasons to route Playwright through a proxy:
- Geo testing: check how a page renders, what prices appear, or which ads load from a specific country or city.
- QA from another location: verify that a checkout flow, language redirect, or regional banner works for users outside your office network.
- Public data collection: gather publicly available information at a polite rate without overloading a single IP address.
- Account and session isolation: keep separate browser contexts on separate IPs when you manage multiple legitimate test accounts, so sessions do not leak into each other.
A proxy does not make automation invisible, and it does not excuse ignoring a site's terms of service or robots.txt. It is one layer in a setup that also needs polite request rates, realistic browser fingerprints, and respect for the target site's rules.
Choosing the Right Proxy Type for Playwright
Not every proxy behaves the same in a real browser. Datacenter IPs are fast and cheap, but they are also easy for anti-bot systems to recognise because they belong to hosting ranges rather than home or mobile networks. Residential IPs come from real home connections, so they look like ordinary visitors. Mobile IPs come from carrier networks and are usually the most trusted, but they cost more.
| Proxy type | Best for in Playwright | Watch out for | | --- | --- | --- | | Datacenter | Fast QA, rank tracking, testing on sites with light protection | Often blocked on protected sites | | Residential | Geo testing, public data collection, multi-account isolation | Slower than datacenter, billed by traffic | | Mobile | High-trust social and app-web flows, strict platforms | Highest cost, limited pool in some regions | | Static ISP | Long sessions, logins, checkout testing | One IP per session, no rotation built in | | Rotating residential | Large crawls, repeated page loads | Session may change mid-flow unless sticky |
For most Playwright work, rotating residential proxies with sticky sessions are the practical default. A sticky session keeps the same IP for a set period, often 10 or 30 minutes, which is long enough to complete a login or a multi-step form without the IP changing halfway through. If your flow is short and stateless, per-request rotation is fine. If your flow involves a login, a cart, or a checkout, use a sticky session or a static IP instead.
Setting Up a Proxy in Playwright
Playwright accepts proxy settings when you create a browser context, not when you launch the browser itself. That distinction matters because it lets you run several contexts in one browser instance, each with its own proxy. This is the cleanest way to isolate sessions.
Python example
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(
proxy={
"server": "http://proxy.example.com:8080",
"username": "your-username",
"password": "your-password",
}
)
page = context.new_page()
page.goto("https://example.com")
print(page.title())
browser.close()
Replace the server, username, and password with the values from your own provider. Do not hard-code credentials in a shared repository. Load them from environment variables or a secrets manager instead.
JavaScript and TypeScript example
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext({
proxy: {
server: 'http://proxy.example.com:8080',
username: 'your-username',
password: 'your-password',
},
});
const page = await context.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
})();
Both examples use HTTP proxies. Playwright also supports SOCKS5 proxies by changing the server scheme to socks5://. SOCKS5 can be useful when you need UDP support or a lower-level tunnel, but for ordinary web automation HTTP and HTTPS proxies are simpler and easier to debug.
One proxy per context
If you need three separate sessions, create three contexts, each with its own proxy. Do not share a context across accounts or test users, because cookies, local storage, and session state live in the context. The pattern looks like this:
- Launch one browser instance.
- Create one context per identity, each with its own proxy and its own storage state.
- Close each context when its task finishes, so cookies do not leak into the next run.
This session-per-identity pattern is the same principle used in API scraping, applied to a real browser. It keeps failures isolated: if one IP is blocked, the other contexts keep working.
Handling Proxy Authentication
Most paid proxies require authentication. Playwright supports username and password directly in the proxy object, as shown above. Some providers instead encode the username and password in the proxy URL, or use IP allowlisting so no password is needed from an approved server. Check your provider's documentation and use the method it supports.
A few practical rules help avoid authentication failures:
- Use session parameters correctly. Some providers let you control sticky sessions, country, or city through the username, for example by appending a session ID. Copy the exact format from your provider; a typo here looks like an authentication error.
- Rotate credentials, not just IPs. If a credential is shared across too many parallel contexts, the provider may rate-limit it. Give each worker its own credential when the plan allows it.
- Handle the 407 response. A 407 status means proxy authentication is required. Log the proxy, the context, and the time when it happens so you can tell a credential problem apart from a blocked IP.
- Never commit credentials. Use environment variables in local runs and a secrets store in CI. A leaked proxy password can be abused to burn through your traffic allowance.
Rotating IPs Without Breaking a Session
Rotation is where many Playwright setups fail. Rotating too aggressively breaks logins. Rotating too slowly gets the IP rate-limited. The right strategy depends on the task.
Per-task rotation
Create a fresh context with a fresh IP for each independent task, such as checking one product page or running one geo test. Close the context afterwards. This is simple, predictable, and easy to debug.
Sticky rotation
Use a sticky session for any flow that spans multiple pages: login, add to cart, fill a form, confirm. Set the sticky duration to cover the whole flow with some margin. If a flow normally takes five minutes, a 10-minute sticky session is safer than a 1-minute one.
Rotation on failure
When a page returns a 403, a 429, or a captcha challenge, do not retry immediately from the same IP. Back off, create a new context with a new IP, and retry once or twice with a longer delay. Log which IP served which request so you can spot a bad IP in the pool instead of blaming the whole provider.
A simple retry pattern in Python looks like this:
import time
def load_with_retry(context_factory, url, max_attempts=3):
for attempt in range(max_attempts):
context = context_factory()
page = context.new_page()
response = page.goto(url, timeout=30000)
if response and response.status < 400:
return page
context.close()
time.sleep(2 ** attempt)
raise RuntimeError(f"Failed to load {url} after {max_attempts} attempts")
Exponential backoff matters. Immediate retries from a new IP still look like a burst, and bursts are exactly what rate limiters are designed to stop.
Testing That Your Proxy Actually Works
Never trust a configuration you have not verified. Before a production run, check four things in a throwaway script:
- IP address: load an IP echo page and confirm the visible IP matches the proxy's location, not your own.
- Headers: confirm the browser sends a normal user agent and language header for the target region.
- Session persistence: log in to a test account, reload the page, and confirm you are still logged in on the same IP.
- Failure behaviour: deliberately request a page that returns an error and confirm your retry logic creates a new context instead of hammering the same IP.
Playwright's tracing and video recording features are useful here. Record a short trace of a failing run and inspect the network requests. Often the problem is not the proxy at all: a missing cookie, a blocked third-party script, or a timing issue where the script clicks before the page finishes loading.
Common Mistakes to Avoid
- Setting the proxy on the browser instead of the context. Playwright ignores proxy settings at launch time for this purpose. Always set them on
new_context. - Sharing one context across accounts. Cookies and storage leak, and one block can take down every session in that context.
- Rotating mid-login. A login flow that starts on one IP and finishes on another looks suspicious and often triggers a security challenge.
- Running headless with a default fingerprint. Headless browsers can be detected. Use Playwright's headed mode for debugging, keep the browser version current, and avoid unusual viewport sizes.
- Ignoring rate limits. A proxy spreads requests across IPs, but it does not remove the need for delays. Space requests out, randomise intervals slightly, and respect crawl-delay guidance where it exists.
- Skipping error logging. Without logs that record the IP, the URL, the status code, and the context ID, every failure looks the same and debugging becomes guesswork.
Playwright Proxy Checklist
Use this checklist before you scale a Playwright job from a handful of pages to hundreds:
- [ ] Proxy is set per context, not per browser
- [ ] Authentication works from a clean run, with no hard-coded secrets
- [ ] Sticky session covers the full login or checkout flow
- [ ] Retry logic backs off and rotates IP on 403, 429, or captcha
- [ ] IP location matches the intended geo for the test
- [ ] Logs record IP, URL, status, and context for every failure
- [ ] Request rate is polite, with delays between pages
- [ ] Target site's terms and robots.txt have been checked
Frequently Asked Questions
Does Playwright support SOCKS5 proxies?
Yes. Set the proxy server to a socks5:// address in the context options. HTTP and HTTPS proxies are more common for web automation and easier to debug, so start with those unless you specifically need SOCKS5 features such as UDP support.
Can I use a different proxy for each page?
Playwright assigns proxies at the context level, not the page level. To give pages different proxies, create a separate context for each proxy. Pages inside the same context share the same proxy, cookies, and storage, which is why the session-per-identity pattern works well.
Why does my Playwright script work locally but fail on a server?
The most common causes are a datacenter IP on the server being blocked, a missing authentication credential in the server environment, or a headless fingerprint difference. Test from the server with an IP echo page first, then compare the browser version and launch options with your local run.
Should I use rotating or static proxies with Playwright?
Use rotating residential proxies with sticky sessions for large, stateless crawls and geo tests. Use static IPs for long logins, checkout testing, and any flow where changing IP mid-session would break the task. Many teams use both: rotating for discovery, static for the flows that must stay stable.
Try It
A proxy setup is only as good as its test. Before you point Playwright at a real workload, run a quick check on your own connection: verify the IP your browser actually shows, confirm the location matches your target region, and try a login flow on a sticky session. You can test your current proxy setup with the proxy test tool, and compare plans on the pricing page when you are ready to scale from a single test context to a full automation fleet.
Related tools & products
Put what you just read into practice with our free tools — or grab clean IPs for the job.
IP Lookup
Check geolocation, ISP and ASN of any IP address.
IP Reputation Check
Score any IP for proxy, hosting and abuse signals.
Proxy Connection Tester
Verify latency and exit IP before you buy.
Residential Proxies
90M+ real household IPs from $4.99 — pay with USDT.
LLM Training Data Proxies
Crawl millions of pages for AI training — cost guide inside.
Web Scraping Proxies
Per-request rotation, city-level targeting, no blocks.
Put it into practice
Get clean residential and mobile proxies live in under two minutes — or test your current IP first.