How to Rotate Proxies in Playwright (2026 Guide)

A short, practical guide to rotating proxies in Playwright — three working methods with copy-paste Python, from per-context swaps to a hands-off rotating gateway.

Author
ProxyHorizon Team
Published
July 18, 2026
7 min read
Expert-Verified
How to Rotate Proxies in Playwright ([year] Guide)

If you scrape with Playwright and keep hitting blocks, CAPTCHAs, or rate limits, the fix is almost always the same: stop sending every request from one IP. Rotating proxies spread your traffic across many addresses so no single one gets flagged — and Playwright makes this refreshingly easy once you know where the proxy option lives.

This is a short, practical guide. You will get three working ways to rotate proxies in Playwright — from a simple per-context swap to a fully managed gateway — with copy-paste Python you can adapt in minutes. Let us get into it.

Why Rotate Proxies in Playwright?

Websites track how many requests come from each IP. Send too many too fast and you get throttled or blocked. Rotating proxies make each request (or each session) look like a different user, which is why proxies are essential for web scraping at scale.

Our take: use residential proxies for strict targets and datacenter for lenient, high-volume ones. Whatever the type, the rotation technique in Playwright is the same.

Rotating proxies with one Playwright context per proxy: each isolated context connects through its own proxy for a fresh IP
The core pattern: one isolated Playwright context per proxy, for a fresh IP each time.

Method 1: A New Context Per Proxy

The cleanest way to rotate in Playwright is one browser context per proxy. Each context is an isolated session with its own cookies, cache, and proxy — so swapping the proxy per context gives you a fresh identity every time.

Text
from playwright.sync_api import sync_playwright

proxies = [
    {"server": "http://p1.provider.com:8000", "username": "user", "password": "pass"},
    {"server": "http://p2.provider.com:8000", "username": "user", "password": "pass"},
    {"server": "http://p3.provider.com:8000", "username": "user", "password": "pass"},
]

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    for proxy in proxies:
        context = browser.new_context(proxy=proxy)
        page = context.new_page()
        page.goto("https://httpbin.org/ip")
        print(page.inner_text("body"))
        context.close()
    browser.close()

Each loop opens a new context on a different proxy, checks the visible IP, then closes it. Closing the context frees resources and guarantees the next request starts clean.

Method 2: Rotate Through a Proxy List

For real scraping you want to pull from a list and cycle through it. A simple helper keeps things tidy and lets you rotate on every request or every N requests.

Text
import itertools
from playwright.sync_api import sync_playwright

proxy_pool = itertools.cycle(proxies)  # cycles forever

urls = ["https://example.com/1", "https://example.com/2", "https://example.com/3"]

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    for url in urls:
        proxy = next(proxy_pool)          # grab the next proxy
        context = browser.new_context(proxy=proxy)
        page = context.new_page()
        page.goto(url, timeout=30000)
        # ... scrape the page here ...
        context.close()
    browser.close()

Using itertools.cycle means the pool never runs out — it loops back to the start. Add a small random delay between requests to look more human and reduce the chance of a block.

Method 3: Use a Rotating Proxy Gateway (Easiest)

The simplest option is to let your provider handle rotation. Most residential providers give you a single gateway endpoint that assigns a fresh IP from their pool on every request — no list to manage at all.

Text
from playwright.sync_api import sync_playwright

# One endpoint; the provider rotates the IP for you
gateway = {
    "server": "http://gate.provider.com:7000",
    "username": "user",
    "password": "pass",
}

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    context = browser.new_context(proxy=gateway)
    page = context.new_page()
    for i in range(5):
        page.goto("https://httpbin.org/ip")
        print(page.inner_text("body"))   # a different IP each time
    context.close()
    browser.close()

This is the least code and the most scalable, because the provider maintains the pool, health-checks IPs, and handles rotation logic for you. For most people, this is the right choice.

MethodEffortBest For
Context per proxyLowSmall, fixed proxy lists
Proxy-list cycleMediumCustom rotation logic
Rotating gatewayLowestScale, hands-off rotation

Best Proxies to Rotate in Playwright

Rotation is only as good as the IPs behind it. These three providers offer clean pools and simple rotating endpoints that drop straight into the code above.

1Decodo

Pool:115M+
Uptime:99.99%
Latency:0.6s
Countries:195+
Huge 97M+ residential IP pool
Beginner-friendly dashboard and documentation
Flexible pay-as-you-go pricing
High success rates on tough targets
Fast 24/7 live chat support
Free trial and money-back guarantee

Best all-rounder. Decodo (formerly Smartproxy) gives you a rotating gateway and sticky sessions with an easy dashboard — ideal for Method 3 above. Great geo-coverage and beginner-friendly pricing make it the safest starting point.

2Oxylabs

Pool:102M+
Uptime:99.99%
Latency:0.6s
Countries:195+
Massive 102M+ IP Pool
Ethically Sourced & Compliant
AI-Powered Web Unblocker
Dedicated Account Manager
Advanced ASN & City Targeting

Best for scale. Oxylabs pairs a huge IP pool with an advanced rotation engine and strong docs — built for large Playwright scraping jobs that need reliability at volume. Premium-priced, but rock-solid.

3IPRoyal

Pool:32M+
Uptime:99.9%
Latency:0.8s
Countries:195+
Traffic never expires (pay-as-you-go)
Ethically sourced residential IPs
Crypto and flexible payment options
Affordable entry pricing
Sticky sessions up to 24 hours

Best value. IPRoyal's non-expiring traffic and friendly pricing make it a great place to test rotation without a big commitment. Compare all options in our proxy directory.

Tips for Reliable Rotation

  • Add random delays. A short, randomized pause between requests looks far more human than rapid-fire calls.
  • Handle failures. Wrap page.goto in try/except and retry on a fresh proxy when one times out.
  • Use sticky sessions for logins. Rotating mid-session breaks logged-in flows — hold one IP for those, and see how proxy rotation works under the hood.
  • Match the proxy type to the target. Residential for strict sites, datacenter for lenient, high-volume ones.
  • Rotate more than the IP. Vary user agents and headers too — the IP is one signal among many.

Frequently Asked Questions

The cleanest way is to create a new browser context for each proxy. In Playwright you pass a proxy object to browser.new_context(proxy=...), and because each context is an isolated session, swapping the proxy per context gives you a fresh IP every time. You can rotate from a fixed list using itertools.cycle, or let a provider's rotating gateway assign a new IP automatically on each request. The gateway approach needs the least code and scales best.
Not on a single page directly, but you can achieve the same result by using a new context per request, each with its own proxy. Playwright sets the proxy at the browser or context level, so the practical pattern is to open a fresh context, make your request, then close it before moving to the next proxy. Alternatively, a rotating gateway endpoint changes the exit IP on every request while you keep using one context, which is simpler for high volume.
Rotating proxies give you a new IP frequently — often on every request — which is ideal for spreading large scraping jobs across many addresses to avoid rate limits. Sticky proxies hold the same IP for a set period, which you need for logged-in sessions or multi-step flows that would break if the IP changed mid-task. In Playwright, use rotating endpoints for bulk data collection and sticky sessions for anything that requires staying logged in.
It depends on the target. Residential proxies use IPs from real homes and rarely get blocked, so they are best for strict sites with strong anti-bot systems. Datacenter proxies are faster and cheaper but easier to detect, making them suitable for lenient, high-volume targets where an occasional block just means a retry. The rotation code in Playwright is identical for both — you only change the proxy credentials, not the technique.
Include the username and password directly in the proxy object you pass to Playwright. The object takes a server field for the host and port, plus username and password fields for authentication, and Playwright handles the rest. This works whether you set the proxy at launch or per context. If your provider uses IP whitelisting instead of credentials, you can omit the username and password and simply authorize your server's IP in the provider dashboard.
A proxy hides your IP, but websites also read your browser fingerprint, headers, and behavior. If those look automated, you can still be blocked even with clean IPs. Rotate user agents, add realistic delays, avoid firing requests too quickly, and consider residential proxies for tough targets. Also check that your proxies are not already flagged — cheap, overused pools are often blocked before you even start, so quality matters as much as rotation.
For small or fixed sets of proxies, managing a list yourself with itertools.cycle gives you full control over the rotation logic. For scale, a rotating gateway is easier and more reliable because the provider maintains the pool, health-checks the IPs, and rotates them for you from a single endpoint. Most people should start with a gateway to keep their code simple, and only build custom list rotation when they need specific control over which IPs are used.
Creating a new context per proxy adds a little overhead compared with reusing one context, but it is usually small and worth the reliability. A rotating gateway avoids that cost because you keep a single context while the exit IP changes behind the scenes. The bigger speed factor is proxy quality: fast, well-maintained residential or datacenter IPs keep latency low, while cheap, congested pools slow everything down with timeouts and retries.

Conclusion

Rotating proxies in Playwright comes down to one idea: give each request or session a different IP. Use a new context per proxy for small lists, cycle through a pool for custom control, or lean on a rotating gateway for hands-off scale — the last option is the right default for most projects.

Pair the technique with a quality proxy pool, add delays and retries, and rotate more than just the IP, and your Playwright scrapers will run far longer before hitting a wall. Ready to set it up? Browse proxies built for rotation in our proxy directory, or compare two providers with our comparison tool.