Skip to content

Puppeteer Rotate Proxies: Per Page, Context or Browser

Pick the unit that rotates, then check the exit IP of each run.

Three ways to rotate

Three ways to rotate
ItemHow the proxy is setWhat you getCost
Context per proxycreateBrowserContext({ proxyServer }) plus page.authenticateSeparate cookies and storage per context, one browser processYou keep a list of proxies
Browser per proxy--proxy-server at launch (proxy-chain if the proxy has a login)Full separation, one process eachMore memory per proxy
One rotating gatewayOne --proxy-server and one loginA new IP for each new connectionNo list; one page can use several IPs unless a session is set

Based on the Puppeteer API pages and the proxy-chain README, read 13 November 2026, and the Proxy302 product facts.

Why there is no per-page proxy

The Puppeteer reference lists proxyServer as an option of a browser context: the proxy for all requests of that context. The launch argument applies to the whole browser. A page cannot be moved to another proxy once it is open, so the smallest unit you can rotate is the context.

Page.authenticate gives the credentials. Puppeteer notes that it turns request interception on behind the scenes, which might affect performance, so call it on the pages that need it and before the first navigation.

A context per proxy

import puppeteer from 'puppeteer'

const proxies = [
  { server: 'http://HOST1:2222', username: 'LOGIN1', password: 'PASSWORD1' },
  { server: 'http://HOST2:2222', username: 'LOGIN2', password: 'PASSWORD2' },
]

const browser = await puppeteer.launch()
for (const p of proxies) {
  const context = await browser.createBrowserContext({ proxyServer: p.server })
  const page = await context.newPage()
  await page.authenticate({ username: p.username, password: p.password })
  await page.goto('https://ipinfo.io/json')
  console.log(await page.evaluate(() => document.body.innerText))
  await context.close()
}
await browser.close()

Example only. Replace HOST, LOGIN and PASSWORD with the values from My assets. Each run prints the IP details for that proxy.

A browser per proxy, with proxy-chain

When you want a whole browser per proxy, the launch flag takes a URL but Chrome does not take the username and password from it. The proxy-chain library starts a small local proxy that holds the login and returns a local URL to use in --proxy-server; you close it when the browser is done.

Chrome supports no authentication methods for SOCKS5, so give the browser an HTTP address.

A browser per proxy

import puppeteer from 'puppeteer'
import { anonymizeProxy, closeAnonymizedProxy } from 'proxy-chain'

const localUrl = await anonymizeProxy('http://LOGIN:PASSWORD@HOST:2222')
const browser = await puppeteer.launch({ args: [`--proxy-server=${localUrl}`] })
const page = await browser.newPage()
await page.goto('https://ipinfo.io/json')
console.log(await page.evaluate(() => document.body.innerText))
await browser.close()
await closeAnonymizedProxy(localUrl, true)

Example only. Needs npm install puppeteer proxy-chain. Replace HOST, LOGIN and PASSWORD.

One rotating gateway

With rotating residential traffic you set one proxy, proxy.proxy302.com on HTTP port 2222, and the exit IP changes by itself. Without a session, every new connection gets a new IP, while a connection that is reused keeps its IP. A page opens several connections, so different requests of one page can leave from different IPs.

If a page must keep one IP, generate the proxy with a session; on the Budget line the console offers 10, 30, 60 or 120 minutes, or your own number of minutes from 1 to 120. For a fixed address for days, use a static IP instead. The Budget line costs US$1.50 per GB.

One browser, one gateway

import puppeteer from 'puppeteer'

const browser = await puppeteer.launch({
  args: ['--proxy-server=http://proxy.proxy302.com:2222'],
})
for (let i = 0; i < 3; i++) {
  const page = await browser.newPage()
  await page.authenticate({ username: 'LOGIN', password: 'PASSWORD' })
  await page.goto('https://ipinfo.io/json')
  console.log(await page.evaluate(() => document.body.innerText))
  await page.close()
}
await browser.close()

Example only. Replace LOGIN and PASSWORD with the values from My assets. If two pages print the same IP, a connection was reused: use a new context or browser for the next job.

Choose and test in 4 steps

  1. Step 1

    Decide what must stay together. A login flow needs one IP for its whole run: use a context or browser per proxy, or a session. Independent page fetches can use the gateway.

  2. Step 2

    Copy host, port, username and password from My assets and use the HTTP protocol, because Chrome has no SOCKS5 login.

  3. Step 3

    Run one of the code examples with two proxies or two runs and compare the ip field of ipinfo.io/json.

    Expected result Different IPs for different contexts or runs, and the same IP inside one session.

  4. Step 4

    Only then add your real task. Respect the terms of the sites you visit and keep the request rate reasonable.

When rotation does not work

Every context prints your own IP

Check Was the page created from the context, not from the browser?

Fix Use context.newPage(), and print ipinfo.io/json for each context.

407 or a login loop

Check page.authenticate must run before the first goto, with the right login.

Fix Copy the username and password again from My assets.

The gateway gives the same IP on every page

Check A reused connection keeps its IP, and a session keeps one IP on purpose.

Fix Close the context or browser between jobs, or generate the proxy without a session.

Stop when If the proxy address does not connect at all, send the order number to Support instead of rotating further.

FAQ

Can Puppeteer use a different proxy for each page?

Not for open pages. The proxy is set per browser at launch or per browser context, so the smallest unit is the context.

How do I pass the proxy username and password?

Call page.authenticate with username and password before the first navigation, or use proxy-chain to hold the login in a local proxy.

Does a rotating proxy change the IP on every request?

No. A new IP is given on each new connection; a reused connection keeps its IP.

Can I use SOCKS5 with a login in Puppeteer?

Not in Chrome: no authentication methods are supported for SOCKS5. Use an HTTP address.

Which Proxy302 product fits rotation?

Rotating residential for a gateway that changes IPs, or a list of static ISP IPs when each job needs a fixed address.

Reference links

5
  1. Puppeteer API: BrowserContextOptions

    Official documentation · Confirmed on:

    Read on 13 November 2026: proxyServer is a proxy server with optional port for all requests of the context, with username and password set in Page.authenticate; proxyBypassList lists hosts that skip the proxy.

  2. Puppeteer API: Page.authenticate

    Official documentation · Confirmed on:

    Read on 13 November 2026: provides credentials for HTTP authentication; request interception is turned on behind the scenes, which might affect performance.

  3. proxy-chain README (apify/proxy-chain)

    Third-party source · Confirmed on:

    Read on 13 November 2026: anonymizeProxy starts a local open proxy that forwards to an authenticated HTTP/HTTPS proxy and returns its URL; closeAnonymizedProxy closes it; the README example launches Puppeteer with --proxy-server set to that local URL.

  4. Chromium notes on proxy settings

    Official documentation · Confirmed on:

    Read on 13 November 2026: no authentication methods are supported for SOCKSv5 in Chrome; --proxy-server takes a URI such as http:// or socks5://.

  5. Proxy302 product facts and price list

    Product observation · Confirmed on:

    Product facts file of the site and line notes, checked 10 and 11 November 2026: rotating residential entry proxy.proxy302.com, HTTP port 2222 and SOCKS5 port 3333; Budget line US$1.50 per GB; a new IP on every new connection unless a session is set; reused (keep-alive) connections keep their IP; Budget line sessions of 1 to 120 minutes; static ISP IPs do not rotate during the lease.

Ready to try it?

Create an account, top up once, then pick rotating residential, static ISP or datacenter IPs and have one running in your browser within minutes.