Quick Answer
To rotate proxies in Playwright, make the browser context your rotation boundary. Create a BrowserContext with one proxy, finish one independent task, close the context, and create the next context with the next proxy or the same provider-managed rotating gateway.
Playwright does not choose or rotate residential IPs. It only routes browser traffic through the proxy configured at browser launch or context creation. The proxy provider decides which exit IP the gateway returns and when it changes.
There are two common setups:
- Provider-managed rotating gateway: reuse one server and credential pair; the provider selects the exit according to its Random or rotating policy.
- Explicit proxy pool: select a proxy configuration in your code and pass it to browser.newContext({ proxy }) in Node.js or browser.new_context(proxy=proxy) in Python.
Do not try to change the proxy on an existing page. Playwright has no page-level proxy setter. Close the old context and create a new one. For login flows, carts, pagination, multi-step forms, and other stateful work, use one Sticky proxy route for the lifetime of the context instead of rotating between page actions.
If you need general authentication, HTTP, HTTPS, SOCKS5, Docker, and browser-launch examples first, start with the parent Playwright proxy guide for Python and Node.js.
Live-test result: On September 3, 2026, a US-scoped Proxidize Sticky route completed 55/55 diagnostic checks through one exit. The equivalent Random route completed 54/55 checks through 45 unique exits. In the Playwright context-per-task sample, 10/10 fresh contexts returned 10 unique exits, all classified as US by the diagnostic service. These are small observed samples, not an SLA or a target-site success benchmark.
Responsible-use note: Use Playwright and proxies only for lawful, authorized browsing, testing, monitoring, and public-data collection. Follow applicable law, website terms, privacy requirements, access controls, and reasonable request rates. Rotation is network infrastructure, not permission to access a target.
Key Takeaways
- Playwright does not rotate IPs by itself. It sends browser traffic to the configured proxy; the gateway or your pool selector controls the exit.
- A BrowserContext is the safest practical rotation unit. It keeps cookies, storage, cache, open connections, and proxy identity aligned for one work unit.
- You cannot change the proxy on a live page or existing context. Close the context and create another with the next proxy configuration.
- Random and Sticky are different policies. Use Random rotation for independent tasks and Sticky routing for multi-step website sessions.
- One page load can generate many requests. A gateway that rotates every request can make one rendered page use several exits.
- Repeated IPs do not prove rotation is broken. Pool selection is not necessarily unique or round-robin, and connections may be reused.
- Bound concurrency independently of proxy count. Unlimited provider connections do not mean a website or browser host should receive unlimited parallel work.
- Rotate only at a safe retry boundary. Do not replay a payment, submission, message, or other non-idempotent action just because the network failed.
- Verify inside the browser context. An IP check made with Node.js fetch() or Python requests does not test Playwright's route.
- The live sample showed why the context boundary matters. Ten Random-route navigations inside one context reused one exit; 10 fresh contexts produced 10 unique exits.
Live Test: Random vs Sticky Residential Proxies in Playwright
On September 3, 2026, we ran headless Chromium with Playwright 1.62.1 for Node.js through live Proxidize residential routes. We compared a Sticky session with a sessionless Random route from the same authorized access point. Both used Proxidize's documented -country-us selector. Account settings were not changed during the test.
The diagnostic destination was https://ipinfo.io/json. Each route received 55 primary attempts across five connection boundaries:
- 10 sequential navigations inside one BrowserContext.
- 10 navigations with a fresh BrowserContext for every attempt.
- 20 requests through one Playwright APIRequestContext.
- 10 requests with a fresh APIRequestContext every time.
- 5 navigations that each launched a fresh Chromium process.
We then made one additional check through each of IPinfo, ipapi.co, and ipwho.is. Raw exit IPs and credentials were not published or retained in the report.
| Route | Primary attempts completed | Unique exits observed | IPinfo US classifications | Three-service follow-up |
|---|---|---|---|---|
| Sticky, `country-us` | 55/55 (100%) | 1 | 55/55 (100%) | All three services saw the same exit and classified it as US |
| Random, `country-us` | 54/55 (98.2%) | 45 | 52/54 (96.3%) | Three additional requests used three different exits; each service classified its own exit as US |
The one failed Random-route request was not retried. Its presence should not be converted into a provider-wide success-rate claim: this test measured the complete path through Playwright, the proxy, TLS, and one public diagnostic service. It did not isolate which layer caused that single failure. Similarly, the two Random exits that IPinfo labeled GB are observed database classifications, not proof of the location a production website would infer. They are a concrete reason to validate geo-sensitive results instead of trusting configuration alone.
The Playwright-only slices make the rotation boundary clearer:
| Route and Playwright boundary | Completed | Unique exits | Consecutive IP changes | Median (p50) | p95 |
|---|---|---|---|---|---|
| Sticky: 10 navigations in one context | 10/10 | 1 | 0/9 | 92 ms | 293 ms |
| Sticky: one fresh context per navigation | 10/10 | 1 | 0/9 | 224 ms | 372 ms |
| Sticky: one fresh Chromium process per navigation | 5/5 | 1 | 0/4 | 454 ms | 474 ms |
| Random: 10 navigations in one context | 10/10 | 1 | 0/9 | 270 ms | 1,132 ms |
| Random: one fresh context per navigation | 10/10 | 10 | 9/9 | 644 ms | 1,090 ms |
| Random: one fresh Chromium process per navigation | 5/5 | 5 | 4/4 | 740 ms | 1,533 ms |
Fresh-process timings include Chromium startup, so they are not proxy-only latency measurements. Even the other figures include DNS, proxy connection handling, TLS, IPinfo response time, and local runtime overhead. Treat them as reproducible methodology and one dated observation—not as a promise about another target, location, workload, or time window.
The useful operational conclusion is narrower and stronger: a new BrowserContext was an effective Random-route rotation boundary in this sample, while reusing one context also reused one exit. The Sticky session preserved one exit even across fresh contexts, fresh HTTP clients, and fresh browser processes. That is why Playwright workers should align their context lifecycle with the intended proxy-session lifecycle.
What Does a Rotating Proxy Mean in Playwright?
A rotating proxy gives browser traffic access to more than one possible exit IP, but “rotation” can describe several different mechanisms.
| Rotation model | What Playwright receives | Who selects the exit? | Best use |
|---|---|---|---|
| Provider-managed gateway | One stable proxy server and credential pair | Proxy provider | Large sets of independent tasks |
| Explicit proxy pool | Several proxy objects or access points | Your application | Deterministic assignment and per-worker isolation |
| Sticky session with controlled renewal | One route held for a work unit, then renewed | Provider policy plus your coordinator | Stateful workflows followed by deliberate identity changes |
| Dedicated proxy with manual/API rotation | One stable endpoint whose upstream IP can be changed | Your application through provider controls | Controlled long-running operations |
The rotation trigger and exit-selection policy are separate. A trigger answers when to ask for another route: every request, every new session, after a timer, after a task, or after a failure. The selection policy answers which route comes next: random, round-robin, least used, location constrained, or health scored.
Playwright only sees the final proxy configuration. It does not know whether the hostname represents one IP, a backconnect gateway, a residential pool, or a dedicated endpoint whose upstream address can rotate.
For the broader network concepts, see What Is IP Rotation?. That guide explains rotation triggers, exit-selection policies, repeated addresses, and the difference between rotating, Sticky, and static proxies.
Does Playwright Rotate Proxies Automatically?
No. Playwright supports proxy configuration but does not contain a residential-IP pool or an automatic proxy-rotation scheduler.
The official Playwright network guide documents HTTP(S) and SOCKSv5 proxies at browser or browser-context scope. The proxy object contains a server and optional HTTP proxy credentials and bypass rules. None of those fields tells Playwright to choose a new exit after a request.
This code sends a context through a proxy:
If proxy.example is a rotating gateway, the provider may assign a different exit according to its policy. If it is a static endpoint, the exit stays the same. The Playwright code is identical.
Playwright also does not offer page.setProxy() or context.setProxy(). Request interception through page.route() can change or fulfill HTTP requests, but it does not replace the browser's network proxy. To assign a different proxy, create another context or launch another browser.
Browser-Level vs Context-Level Proxy Rotation
Playwright can set the proxy globally when launching the browser or separately when creating a context.
| Scope | Node.js | Python | Rotation consequence |
|---|---|---|---|
| Browser | `chromium.launch({ proxy })` | `chromium.launch(proxy=proxy)` | All contexts share one configured gateway |
| Context | `browser.newContext({ proxy })` | `browser.new_context(proxy=proxy)` | Each context can receive its own gateway or pool member |
| Page | Not supported | Not supported | Create another context instead |
| Individual subrequest | Not a Playwright proxy scope | Not a Playwright proxy scope | Provider behavior may still rotate upstream exits |
Use browser-level configuration when one browser process should never make a direct request and every task uses the same gateway policy. Use context-level configuration when workers need separate credentials, locations, customers, sessions, or proxy assignments.
The official BrowserContext documentation describes contexts as isolated, incognito-like profiles with separate cookies, local storage, and session storage. That makes a context the natural place to align three things:
Closing a context also closes its pages and network connections. Keeping the browser process open while replacing contexts is usually much cheaper than launching a completely new browser for every URL.
How to Test a Provider-Managed Rotating Gateway in Node.js
As of September 3, 2026, the current stable npm package is playwright==1.62.1. Install it and Chromium:
Store the proxy configuration outside the source file:
The following program creates a clean context for every observation while sending all of them to the same rotating gateway:
Run it using Node.js environment-file support:
This observes the IP used for each check page. It does not prove that the next destination request will use the same address when the gateway rotates on every request or connection. It also does not require every observation to be unique. Use the test to confirm that traffic is proxied and that the gateway's observed behavior matches the documented policy over a meaningful sample.
Do not call a third-party IP service before every production navigation. That consumes bandwidth, adds another dependency, and may itself be rate limited. Use checks during setup, health sampling, and incident diagnosis.
How to Use a Rotating Proxy With Playwright in Python
The current stable Python package checked for this guide is playwright==1.62.0. Install it in a virtual environment:
This asynchronous example uses the same environment values and creates one context per check:
The synchronous Playwright API uses the same proxy dictionary and context lifecycle. The parent Playwright proxy setup guide includes complete synchronous and asynchronous setup, authentication, SOCKS5 limitations, and Docker examples.
How to Rotate Through an Explicit Proxy Pool
Use an explicit pool when you need to know which proxy configuration was assigned to each task. Keep the credentials in an ignored JSON file or secret store rather than hard-coding them in the program.
The following Node.js example assigns proxies round-robin and runs no more than three browser contexts simultaneously:
This code rotates configurations, not necessarily physical IPs. Two gateway credentials can select the same upstream IP, and one rotating gateway can expose many IPs. Record an internal proxy or access-point identifier for debugging, but keep passwords and full connection strings out of logs.
Round-robin is predictable, not automatically optimal. A production pool may also track temporary quarantine, health, location, recent failures, bandwidth budget, and which routes are already assigned to stateful work.
Rotating vs Sticky Proxies for Playwright
Use rotation between independent tasks. Use a Sticky proxy for the full lifetime of a coherent browser session.
| Playwright task | Recommended proxy behavior | Reason |
|---|---|---|
| Independent public-page checks | Rotate between contexts | Each task can start with clean browser and network state |
| Country-by-country availability check | One verified route per country and task | Keeps location explicit and auditable |
| Pagination | Sticky through the page sequence | The website may bind state to cookies and IP |
| Login or authenticated session | Sticky until logout or expiration | Mid-session changes can trigger security checks or invalidate state |
| Cart, checkout, or multi-step form | Sticky for the entire workflow | Do not change identity between dependent steps |
| Long research journey | Sticky within one source journey; rotate between unrelated journeys | Preserves continuity without coupling unrelated work |
| Failed proxy before any side effect | Retire context and rotate within budget | Safe to restart from the beginning |
| Failure after an external write | Verify outcome before any retry | Replaying may duplicate the action |
One rendered page is not one network request. It can load HTML, scripts, style sheets, fonts, images, API calls, analytics, and WebSockets in parallel. If the gateway rotates on every subrequest, the destination may observe several exit IPs for one page.
That behavior can work for simple retrieval, but it is a poor default for workflows that depend on cookies, authentication, carts, localized state, or consistent fraud checks. In those cases, select a Sticky access point and rotate only after closing the associated context.
The detailed proxy sessions for AI agents guide separates agent-run state, browser state, website state, and proxy state. The same lifecycle model applies to non-agent Playwright workers.
How to Use Proxidize Rotating Residential Proxies With Playwright
Proxidize Residential Proxies support rotating and Sticky sessions, country, city, and ISP targeting, and standard HTTP(S) and SOCKS5 access. Playwright needs the server, port, and—when using HTTP proxy authentication—username and password generated for the access point.
The website request path is:
Use this workflow:
- Create a Residential Proxy access point in the Proxidize dashboard.
- Choose the required country, city, or ISP only when the task genuinely needs that location.
- Select Random for independent tasks or Sticky for a coherent browser session.
- Copy the generated HTTP proxy server and credentials into a secret store.
- Pass those values as separate server, username, and password fields.
- Create a new context at the beginning of each work unit.
- Verify the observed IP and location from inside a sample context.
- Close the context before starting a task that should receive a different identity.
With a Random residential access point, the endpoint can remain the same while Proxidize selects exits according to the access-point policy. With a Sticky access point, keep the context and its route together until the work unit finishes. Playwright does not need provider-specific code for either mode.
Do not paste the combined credential string directly into source code or a prompt. Split it into the documented Playwright fields and inject it at runtime. Avoid printing the username because provider usernames can encode customer, access-point, product, location, or session information.
Want to test the pattern? Create a Proxidize Residential Proxy access point and use the generated endpoint in the gateway example.
How Should Retries Work With Proxy Rotation?
Classify the failure before rotating. “Try another IP” is not a complete retry policy.
| Failure | Rotate immediately? | Better response |
|---|---|---|
| Missing or invalid credentials / HTTP 407 | No | Correct or refresh the credential configuration |
| Proxy hostname or port is unreachable | Maybe | Check configuration and provider health; quarantine a failed pool member |
| One connection reset | Not necessarily | Retry once with backoff if the operation is safe |
| Navigation timeout before any action | Maybe | Distinguish slow target from failed route; retry within a small budget |
| HTTP 429 | Usually no | Honor `Retry-After`, reduce target concurrency, and slow the schedule |
| HTTP 403 or challenge page | Not reflexively | Confirm authorization, content requirements, headers, browser behavior, and target policy |
| Geo mismatch | Yes, at a clean boundary | Close the context and choose a correctly targeted route |
| Failure after form submission or other write | No blind retry | Verify whether the first action succeeded |
Use exponential backoff with jitter for transient connection failures and cap attempts per task. Retire both the context and its proxy assignment when changing identity; carrying cookies from the failed context into a new IP can create a more suspicious or inconsistent session.
Rotation should not be used to ignore a destination's explicit rate limit. A request limit applies to the workflow, not merely one IP address. Bound load by target and follow applicable rules even when the proxy pool can supply more exits.
How Do You Control Concurrency Across Rotating Contexts?
Concurrency has at least three independent limits:
Set the worker count to the lowest safe capacity across the browser host, proxy plan, destination, and downstream parser. A provider may allow many connections while Chromium memory or the target's reasonable request rate remains the real limit.
Avoid launching thousands of contexts through one unbounded Promise.all(). Use a worker queue or semaphore. Give each worker a context, a proxy assignment, a timeout, and a cleanup path. Always close contexts in finally so a failed navigation does not leak cookies, sockets, video handles, or proxy leases.
Do not share one context among concurrent tasks that are supposed to have separate identities. Pages inside one context share cookies and proxy configuration even when they navigate simultaneously.
How Do You Verify Playwright Proxy Rotation?
Verify the route from inside the Playwright page, then distinguish four different questions:
- Was the browser proxied? The observed IP should differ from the automation host's direct address.
- Did the exit change? Compare observations across independent contexts or documented rotation boundaries.
- Did the location match? Verify country or city through an approved geo-check and, when possible, confirm what the target itself displays.
- Did the workflow stay coherent? Confirm cookies, language, price, storefront, and other state match the intended route.
Do not require every rotation check to produce a never-before-seen IP. Random selection permits repeats, large networks can still select the same exit twice, and connection reuse may keep one address longer than expected.
For Sticky routes, run two checks during the same work unit and confirm continuity. For Random routes, sample across separate contexts and report the number of observations, unique addresses, time window, location filter, and rotation boundary. If you publish a small-sample completion rate, label it as an observed diagnostic result rather than turning it into a provider-wide success-rate or SLA claim.
An external IP lookup only observes its own request. If a random gateway can change between requests, that result is not proof of the exact IP seen by a later target. Target-side logs or an endpoint you control provide stronger end-to-end evidence.
Common Playwright Proxy-Rotation Mistakes
Trying to change the proxy on an existing page
Proxy settings are established at browser or context creation. Close the context and create another with the next assignment.
Rotating between steps of one workflow
Cookies, local storage, CSRF state, login state, and server-side risk signals can depend on IP continuity. Keep one Sticky route until the coherent work unit ends.
Assuming a new context guarantees a new IP
A new context creates clean browser state and new connections, but the provider may legitimately select the same exit again. Only the provider's rotation contract controls that behavior.
Assuming one page equals one request
A browser can open many parallel connections for one page. Per-request rotation can split a page across multiple exits.
Verifying with Node.js fetch or Python requests
Those calls use their own network stacks. Navigate to the check endpoint inside the proxied Playwright context.
Reusing storage state across unrelated IP identities
A saved cookie jar can connect two supposedly isolated tasks. Restore storage only when the website identity and proxy route are intended to remain linked.
Logging complete proxy strings
Combined proxy URLs often include passwords and customer metadata. Log an internal assignment ID, not the endpoint or credentials.
Rotating in response to every 403 or 429
The problem may be authorization, rate, browser behavior, content availability, or target policy. Diagnose the layer and slow down before changing identities.
Troubleshooting Playwright Rotating Proxies
| Symptom | Likely cause | Fix |
|---|---|---|
| Every context shows the host's direct IP | Proxy was not attached to the browser/context, or target is in `bypass` | Inspect the context creation path and remove unintended bypass entries |
| HTTP 407 | Missing, malformed, or expired proxy credentials | Pass HTTP credentials in separate `username` and `password` fields |
| Same IP appears repeatedly | Sticky policy, connection reuse, random repeat, small location pool, or static endpoint | Check access-point mode and test across documented boundaries |
| IP changes inside one page flow | Gateway rotates per request/connection | Use Sticky mode for that context |
| Cookies disappear after rotation | A new context intentionally starts with clean state | Keep one context for the workflow or restore approved storage deliberately |
| Contexts leak identities | Pages share one context or storage file | Create isolated contexts and separate storage namespaces |
| Correct country but wrong page content | Website uses cookies, language, account, DNS, or other signals too | Align browser state and verify what the target shows |
| Rotation increases 429 responses | Workflow concurrency is too high | Reduce per-target rate and honor server guidance |
| Browser memory keeps growing | Contexts or pages are not closed after failures | Close the context in `finally` and bound workers |
| SOCKS5 authentication fails | Playwright proxy credentials apply to HTTP proxy authentication | Use an IP-allowlisted SOCKS5 route or authenticated HTTP endpoint; see the parent guide |
Playwright Rotating Proxy Production Checklist
- Use the current Playwright package and install its matching browser build.
- Keep proxy credentials in environment or secret storage, not source code.
- Pass HTTP credentials as separate username and password fields.
- Choose browser-level or context-level scope deliberately.
- Use one context per isolated work unit.
- Use Random rotation only for tasks that tolerate identity changes.
- Use Sticky routing for login, carts, pagination, forms, and multi-page journeys.
- Close a context before assigning the next proxy.
- Verify IP and location from inside a Playwright context.
- Do not assume every rotation produces a unique address.
- Bound browser, proxy, and per-target concurrency separately.
- Classify errors before rotating.
- Cap retries and add exponential backoff with jitter.
- Never blindly retry a non-idempotent action.
- Keep cookies and storage isolated between unrelated identities.
- Log assignment IDs and outcomes, not credentials.
- Quarantine unhealthy pool members temporarily rather than retrying them forever.
- Follow applicable laws, website terms, access controls, privacy requirements, and reasonable rates.
Conclusion
The reliable way to use rotating proxies with Playwright is to rotate at the browser-context boundary. One task receives one context and one proxy policy. The context closes before a new identity is assigned. Stateful work stays on a Sticky route; independent work can use a Random gateway or explicit pool.
That design keeps browser cookies, website state, proxy identity, retries, and logs understandable. It also avoids the common mistake of treating every browser subrequest as a safe rotation point.
Use the parent Playwright proxy guide for general Python, Node.js, authentication, SOCKS5, and Docker setup. Use the IP rotation guide for network policy, and Proxy Sessions for AI Agents for coordinated browser, website, agent, and proxy state.
When you are ready to test with a managed residential gateway, explore Proxidize Residential Proxies.