Proxies for Puppeteer, Playwright and Selenium
One endpoint for headless Chrome or Firefox, with a session id that holds a whole page load on one exit.
From $7.47 a month for 3 GB
That is $2.49/GB at 3 GB, and the rate falls as the volume rises.
For targets that refuse or challenge datacenter ranges
- Rotating Datacenter from $5.90 a month for 10 GB.Cheaper, where the target accepts hosting ranges
- Rotating Unmetered from $29.00 a month for 250 connections, with no bandwidth meter, priced per concurrent connection.When page weight rather than request count would decide the bill
- No bandwidth meter on Rotating Unmetered: priced per concurrent connection.
- Residential exits from an upstream partner network in 170+ countries.
- HTTP(S) / SOCKS5 on one credential; Puppeteer, Playwright and Selenium all take it.
Billed monthly. Cancel anytime in your settings, and you keep access to the end of the period you have paid for. Refund terms.
Point the browser you already have at the real target through a free allocation of shared datacenter proxies first, no card required.
Is this the right product for you?
The tool does not decide which product you need; the target does. Point the script you already have at your real target through the free datacenter allocation. If the page renders, rotating datacenter is the cheaper buy. If it comes back challenged or empty, a larger datacenter plan will not change that, and residential is where to start; it can be refused too, so buy the smallest plan and check before scaling. A third case is specific to browsers: a headless page load moves several times the bytes an HTTP client does, so Rotating Unmetered charges for the sessions you hold open rather than the bytes they move.
Plans and pricing
Pick any size below and that size is what reaches checkout. Billed monthly. Card and PayPal renew automatically until you cancel; a Bitcoin plan does not renew on its own, so you renew it from your dashboard. Cancel anytime from your own settings. You keep access until the end of the period you have paid for.
Residential
High-quality residential IPs for accurate, location-specific data
| Bandwidth | Price per GB | Total | Discount | Select this plan |
|---|---|---|---|---|
| 3 GB | $2.49/GB | $7.47 /mo | - | |
| 5 GB | $2.29/GB | $11.45 /mo | Save 8% | |
| 10 GB | $1.99/GB | $19.90 /mo | Save 20% | |
| 25 GB | $1.69/GB | $42.25 /mo | Save 32% | |
| 50 GB | $1.39/GB | $69.50 /mo | Save 44% | |
| 100 GBPopular | $0.79/GB | $79.00 /mo | Save 68% | |
| 250 GB | $0.75/GB | $187.50 /mo | Save 70% | |
| 500 GB | $0.70/GB | $350.00 /mo | Save 72% | |
| 1 TB | $0.65/GB | $650.00 /mo | Save 74% | |
| 5 TB | $0.49/GB | $2,450.00 /mo | Save 80% |
- Bandwidth
- Per GB pricing
- Threads
- Unlimited
- Protocols
- HTTP(S) / SOCKS5
Rotating Datacenter
Auto-rotating datacenter proxies across the US, Italy and Spain, billed by bandwidth usage. Per-request rotation by default, or pin one exit with a session id
| Bandwidth | Price per GB | Total | Discount | Select this plan |
|---|---|---|---|---|
| 10 GB | $0.59/GB | $5.90 /mo | - | |
| 25 GBPopular | $0.52/GB | $13.00 /mo | Save 12% | |
| 50 GB | $0.47/GB | $23.50 /mo | Save 20% |
- Bandwidth
- Per GB pricing
- Threads
- Unlimited
- Protocols
- HTTP(S) / SOCKS5
- Sessions
- Per request, or sticky up to 30 min
Rotating Unmetered
Rotating datacenter proxies with no bandwidth meter, priced by how many connections you run at once rather than how many bytes you move. Per-request rotation by default, or pin one exit with a session id
| # of Connections | Price per Connection | Total | Discount | Select this plan |
|---|---|---|---|---|
| 250 connections | $0.116 | $29.00 /mo | - | |
| 600 connections | $0.098 | $59.00 /mo | Save 15% | |
| 1,200 connectionsPopular | $0.082 | $99.00 /mo | Save 29% | |
| 2,000 connections | $0.074 | $149.00 /mo | Save 35% | |
| 4,000 connections | $0.062 | $249.00 /mo | Save 46% |
- Bandwidth
- Unlimited
- Threads
- 250 to 4,000
- Protocols
- HTTP(S) / SOCKS5
- Sessions
- Per request, or sticky up to 30 min
What you are actually buying
- Residential in 170+ countries
- Country, state, city and ASN targeting, all set in the proxy username rather than by switching endpoints. These exits come from an upstream partner network and are resold, which is why residential is billed by the gigabyte.
- Both protocols, no upcharge
- HTTP(S) / SOCKS5 on every tier of this product, on one credential, at no extra charge.
Connection details
One endpoint per product, and the browser only ever holds one of them. Rotating Datacenter is gw-rotating_datacenter.node4.io:8083, and Rotating Unmetered is gw-rotating_unmetered.node4.io:8084. Country and session are segments of the username, so a browser changes market without changing endpoint.
Code examples
npm install puppeteerimport puppeteer from "puppeteer";
// The address is a Chromium launch flag, and Chromium DROPS any
// credentials written into it. They go to page.authenticate instead.
const browser = await puppeteer.launch({
args: ["--proxy-server=http://gw-rotating_datacenter.node4.io:8083"],
});
const page = await browser.newPage();
// The session segment holds one exit for this page load and the flow
// after it. Without it, the document and its scripts can arrive from
// different exits.
await page.authenticate({
username: "USER-session-482913",
password: "PASS",
});
await page.goto("https://api.ipify.org");
console.log(await page.$eval("body", (el) => el.innerText));
await browser.close();npm install playwrightimport { chromium } from "playwright";
// Playwright carries the address and the credentials in one option,
// and takes it on a context as well as on launch, so one browser
// process can hold several contexts on several exits.
const browser = await chromium.launch();
const context = await browser.newContext({
proxy: {
server: "http://gw-residential.node4.io:8082",
username: "USER-country-de-session-a41f9c",
password: "PASS",
},
});
const page = await context.newPage();
await page.goto("https://api.ipify.org");
console.log(await page.textContent("body"));
await browser.close();pip install seleniumfrom selenium import webdriver
# WebDriver has no username or password field for an HTTP proxy, and
# Chromium ignores credentials written into the flag. Register this
# machine's public address on the Auth & IP Access page and send none.
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--proxy-server=http://gw-rotating_datacenter.node4.io:8083")
driver = webdriver.Chrome(options=options)
driver.get("https://api.ipify.org")
print(driver.find_element("tag name", "body").text)
driver.quit()A page load is not a request. Opening one URL in headless Chrome fires dozens: the document, then the scripts, fonts, images and third-party endpoints the document references, all through the proxy you configured, over connections the browser then keeps alive for the next navigation. Two things follow from that, and they are the whole reason this decision differs from the one a crawler faces. Per-request rotation scatters a single page across several exits, which is a pattern no ordinary visitor produces. And the bytes per page are a multiple of what an HTTP client moves, which puts the billing unit into the buying decision rather than leaving it to the invoice.
Start by finding out what your target refuses
The one thing that genuinely differs between targets is whether datacenter ranges are accepted at all, and with a browser automation job you are unusually well placed to find out, because the script already exists. Every verified account gets a free allocation of shared datacenter proxies with no card, so run your existing Puppeteer, Playwright or Selenium job against the real target through those addresses and read what comes back. A rendered page means datacenter is the right product and the cheapest thing that works. A challenge, an interstitial, or a shell where the content should be means that target classifies hosting ranges as a class, and no larger datacenter plan changes the answer; residential is what you need. Buying more datacenter at that point is spending money to relearn the same fact.
The same decision, walked from the product end rather than the tool end, is in choosing the right proxy type.
One page load, many requests, and why a browser wants a session
Per-request rotation is the right default for a crawler, where each request stands alone and a fresh address per request is the point. A browser is the case where it is usually wrong. Every subresource is its own request through the same proxy configuration, so under per-request rotation the document and its scripts can leave from different networks within the same second, and the next navigation may reuse any connection that is still open. Most targets never notice. Targets that tie a session to an address do, and the symptom is a login that succeeds followed by a page that treats you as a stranger. Adding a session segment to the username pins one exit for the whole flow. On the rotating tiers that pin holds for up to 30 minutes, measured from when it is first assigned rather than from your last request, so a job that runs longer should mint a fresh session id and carry on. Residential accepts session ids too, but its stickiness is delegated to the upstream partner network rather than to our own session lease, so treat the hold as best effort there and build the flow to survive the address changing under it.
What actually breaks when the exit changes mid-flow is covered in sticky versus rotating sessions.
Wiring it in Puppeteer and Playwright
Both set the proxy at the browser level and neither needs a plugin. In Puppeteer the address is a Chromium launch argument passed in args, and the credentials are a separate step, because Chromium discards a username and password embedded in that flag: page.authenticate carries them instead, once per page. Playwright has a first-class proxy option taking server, username and password, accepted both at launch and on browser.newContext, which is what lets one browser process hold several contexts on different exits. Because targeting and session ids ride in the username on our gateways, choosing a country or pinning a session is a string you build rather than an endpoint you switch, so the wiring below is the whole integration and none of it changes when the pool does.
The 407s, the per-context caveat and the DNS and WebRTC side channels are in proxy authentication in Puppeteer and Playwright.
- Puppeteer: args: ["--proxy-server=http://HOST:PORT"], then page.authenticate({ username, password })
- Playwright: proxy: { server, username, password }, on launch or on browser.newContext()
- Country and session ride in the username: USER-country-de-session-482913
Selenium is the awkward one, and the reason is not your code
Selenium speaks WebDriver, and the WebDriver proxy capability has fields for the proxy host, the scheme and a username and password for SOCKS, and no username or password for an HTTP proxy at all. Chromium then ignores credentials embedded in the proxy-server flag, so the browser connects unauthenticated, is refused, and raises a dialog drawn outside the page where no element lookup can reach it. Two arrangements avoid the problem rather than working around it. The first is to register the public address of the machine running Selenium and connect with no credentials at all: IP whitelisting is available on every product, and on the rotating gateways a whitelisted machine can still send the username with an empty password to keep country and session targeting, while a whitelisted residential connection sends no username, which makes its exit untargeted. The second is Selenium 4's own authentication handler, which answers the challenge over DevTools with no extension and no local forwarder.
Four authentication routes with working code for each, and the three ways to rotate, are in rotating a Selenium proxy, and the auth traps on the way.
A browser moves far more per page than a crawler does
This is the part that decides the invoice, and it is the one argument on this page that a Scrapy buyer never has to make. A crawler fetches the document and parses it. A headless browser fetches the document and then everything the document asks for: the framework bundle, the fonts, the images, the analytics beacons. On a per-gigabyte product that multiple lands directly on the bill, so the cheapest rate per gigabyte is not automatically the cheapest way to run a browser. Rotating Unmetered has no byte meter at all and is priced by how many connections you hold open at once, which for this workload is a number you already know: it is how many browser workers you run. Blocking images, fonts and media in the browser cuts the same bill on a metered product, and is worth doing before you size anything.
Where each billing unit wins, with the arithmetic rather than the adjective, is in unmetered billing versus per GB.
What a proxy fixes here, and what it leaves standing
Rotation and residential exits solve one problem: per-address accounting. Rate limits, per-IP request caps and single-address bans stop deciding your outcome when requests arrive from different networks. They do nothing about the rest of what a browser announces about itself. An automated Chromium is identifiable from its own runtime properties, its TLS handshake, its font and codec list and its timing, and a target correlating on those will connect your sessions whatever the exit is. A cookie set behind one exit and replayed behind another is a stronger signal than either exit was on its own. Buy proxies for the address problem, treat the browser's own footprint as separate work, and change one variable at a time when something starts failing, because otherwise you never learn which of the two it was.
What you are buying, by product
Residential exits are real consumer connections in an upstream partner network, billed by the gigabyte, and are what a target refusing datacenter ranges will accept. Rotating datacenter hands you a fresh address per request from blocks node4 owns in the United States, Italy and Spain, also billed by the gigabyte, and is the cheaper answer where a target tolerates hosting traffic but limits each address. Rotating Unmetered is the same pool and the same gateway with the byte meter removed, priced by concurrent connections instead. Dedicated datacenter is priced per address with nothing metering the traffic, which suits a long-running browser job against a tolerant target where the bytes would otherwise dominate the cost.
The same four products compared against competitors rather than against each other, for this workload specifically: how the proxy types rank for a browser job.
How it compares
| Feature | This page | Rotating datacenter | Dedicated datacenter |
|---|---|---|---|
| IP changes | Every request, or sticky | Every request, or sticky | Fixed |
| IP origin | Partner network | IP blocks we own | IP blocks we own |
| Billing | Per GB | Per GB, or per connection unmetered | Per proxy / month |
| Geo targeting | Country, state, city | Country | Location of the block |
| Credentials in the browser | Username and password, or whitelist | Username and password, or whitelist | Username and password, or whitelist |
| Entry price | $2.49/GB at 3 GB, $0.49 at 5 TB | $0.59/GB at 10 GB, $0.47 at 50 GB | $1.49/proxy at 5, $0.75 at 1,000 |
| Browser workload it suits | Targets refusing hosting ranges | Targets that accept them | One lasting identity per worker |
What people use these for
Sites that render in the browser
A parser handed a single-page application gets an empty shell. A headless browser gets the DOM the user sees, and the proxy decides which network it is built from.
Checking a market you do not sit in
Run the suite through an exit in the country you sell to and read the prices, banners and consent flows a visitor there meets.
Logged-in and multi-step journeys
Pin a session id per worker so the login, the cart and the confirmation all leave from one exit instead of three.
Worker pools you can size
Rotation and concurrency are separate dials. One endpoint serves every worker, and on the connection-priced tier the worker count is exactly the thing you are buying.
Frequently asked questions
Which proxies should I use with Puppeteer, Playwright or Selenium?
Test before you decide, because the answer is a property of your target rather than of the tool. Run your existing script against the real target through the free datacenter allocation. If the page renders, datacenter is the cheapest thing that works and rotating datacenter is where to start. If it comes back challenged or empty, that target refuses hosting ranges and residential is the product; a bigger datacenter plan returns the same result. The one browser-specific adjustment is the billing unit: a headless page load moves several times what an HTTP client does, so measure a short run before sizing a per-gigabyte plan.
How do I pass proxy credentials to a headless browser?
It depends on the tool, and Chromium is the reason it is not uniform. Puppeteer takes the address as a launch argument and the credentials separately through page.authenticate, because Chromium discards a username and password written into the launch flag. Playwright takes both together in its proxy option, on launch or on a browser context. Selenium has nowhere to put an HTTP proxy credential at all, since the WebDriver proxy capability defines a username and password only for SOCKS, so it uses either IP whitelisting or Selenium 4's DevTools authentication handler.
Can each browser context have its own exit IP?
Yes, in both Puppeteer and Playwright, and it is the cheapest rotation a browser can do. A context is an isolated profile inside a running browser, so replacing one costs milliseconds where relaunching the browser costs a process tree and a couple of seconds. Give each context its own session id in the username and each one holds its own exit; close and reopen a context to move it to a fresh address. Chromium on some platforms has ignored a context-level proxy unless the browser itself was launched with one, so launch with a placeholder address and assert the exit before trusting it.
Does SOCKS5 work with a headless browser?
Chromium accepts a SOCKS5 proxy in the same launch flag and Playwright accepts a socks5 scheme in its proxy option, so the address half works. The credential half does not: the mechanism that answers an HTTP proxy challenge has no SOCKS equivalent, so a SOCKS5 browser job authenticates by IP whitelist, which is available on every product. SOCKS5 itself is a paid feature and is included on every paid plan at no extra charge; the free allocation is HTTP and HTTPS only.
How long does a sticky session hold one exit?
On the rotating tiers, for up to 30 minutes, measured from when the pin is first assigned rather than from your most recent request, so a busy session does not extend its own window. Work that outlives it should mint a fresh session id and carry on rather than expecting the original to persist. Residential accepts a session id in the username too, but its stickiness is handled by the upstream partner network rather than by our own session lease, so no time-bound figure is published for it and a multi-step flow should tolerate the exit changing.
Will proxies stop my headless browser getting blocked?
They remove one cause and leave the others standing, and it is worth being clear about which. Changing the exit address defeats anything counted per address: rate limits, per-IP caps, a single banned address. It does not touch what the browser says about itself, so an automated Chromium's runtime properties, TLS handshake and timing still travel with the session, and a target correlating on those will connect your requests from any exit. Treat the two as separate work and change one at a time.
How much bandwidth does a headless browser use?
Enough more than a crawler that it is worth measuring rather than estimating. Multiply pages by the full weight of the page, not the weight of its markup, because the browser fetches the scripts, fonts and images a parser skips. Run a bounded, representative slice of the job and read the gigabytes off the usage page; that gives you cost per unit of work and it scales from there. Blocking images, media and fonts at the request level cuts it sharply, and moving to a connection-priced plan removes the meter from the question entirely.
Do I need one proxy per browser?
Not with a gateway, which is most of why a gateway suits this workload. Every browser and every context points at one hostname and port with one credential, and the exit is chosen behind it, so a pool of forty workers needs no list of forty addresses and nothing to health check. Give each worker its own session id if you want each one to keep a stable identity. Per-address products are the other shape: they are worth it when you want a specific, lasting identity per account rather than a fresh exit per worker.
Guides for Proxies for Puppeteer, Playwright and Selenium
Setup, targeting and troubleshooting, written for people already running this in production.
- Proxy authentication in Puppeteer and Playwright, and the leaks around it
- Puppeteer rotating proxy, per browser or per context
- Rotating a Selenium proxy, and the auth traps on the way
- Picking the proxy type a Puppeteer or Playwright job needs
- Setting a proxy in an ordinary browser, by hand
- What breaks when the exit IP changes mid-flow
- Pinning one exit for a multi-step flow
- Running many browser workers without tripping a per-IP cap
- Unmetered rotating versus per-GB, and when each one wins
- Registering the address a CI runner egresses from
- Fixing 407 Proxy Authentication Required
- Reading a proxy error code before blaming the pool
- Why a target starts refusing an address that worked
- Sizing a proxy pool against a page count
- Practices that keep a crawl inside a site's tolerance
- Wiring proxy rotation into Scrapy, where no browser is needed