Puppeteer Works Fine — the IP Gives It Away
Puppeteer drives a real Chrome build: real rendering, real cookies, real font stack. Yet runs still come back with empty selectors, challenge pages and half-filled datasets, and the code is rarely at fault. When requests leave through a carrier IP, they arrive as ordinary mobile traffic, so the script collects pages instead of captchas — and the invoice covers a rented port, not thousands of wasted retries.
| IP source | What the script gets | What you pay for |
|---|
| Hosting ranges | Challenges and empty responses early in the run | Cheap IPs, expensive engineering time |
| Per-GB residential pools | Passes many targets, drops below 80% on aggressive ones | Every retry billed again as traffic |
| Mobile carrier ports | 95–99% success on the same aggressive targets | Flat price per port, unlimited traffic |
The difference matters most on targets where a failed run costs more than the infrastructure: SERP snapshots, marketplace pricing, travel inventory, ad verification. On those jobs a mobile exit turns a scraper that needs babysitting into one that finishes on schedule.
Puppeteer proxy setup in one launch flag
No wrapper is needed to route headless Chrome. Declare const browser = await puppeteer.launch with args containing --proxy-server=host:port, open const page = await browser.newPage, then pass credentials through page.authenticate with the login and password from the dashboard. No extra npm package, no custom library, no build step — the first authenticated run happens in minutes instead of a sprint.
Teams that prefer IP whitelisting can drop the authenticate call entirely and bind the port to a server address. Both authentication methods are supported, so a CI runner and a local machine can share the same port list without a support ticket in between.
One Port per Identity, Not One Port for Everything
Each new call to browser.newPage inherits the browser-level route, which is exactly what you want for a single crawl and exactly what you do not want for account work. Separate identities need separate launches or separate browser contexts, each pinned to its own port. Mixing profiles on one exit links them together, and the cost of that mistake is a whole batch of accounts instead of one.
When only part of the traffic should be proxied — an API call, a token refresh, a webhook check — an npm package such as https-proxy-agent supplies a custom agent for the request layer while Chrome keeps its own exit. That split keeps light requests fast and heavy browser sessions clean, so one flagged profile no longer drags the whole farm down.
Rotation That Matches the Job
Scraping and account farming need opposite behavior from the same port. Rotation control is what lets one subscription serve both without renting twice.
| Mode | Fits | Where it works |
|---|
| Sticky session | Logins, cart flows, paginated crawls | Regular |
| Change by link (API) | New IP after every N pages, triggered from code | Regular |
| Timer rotation | Overnight jobs left unattended | Regular |
| Automatic every 2–5 min | Simple parsing where session continuity is optional | Lite |
A rotation link called from the script is the cheapest form of retry logic there is: when a target starts throttling, the next page loads from a fresh carrier IP instead of failing the batch. Long jobs finish on the first attempt more often, which is time nobody has to spend re-running yesterday's crawl.
Where the Network Layer Stops
A puppeteer proxy solves identity at the network level and nothing above it. Headless Chrome still announces itself through its fingerprint, so a stealth plugin or an antidetect profile belongs in the stack next to the port. Behavior counts too: randomized delays and human-scale navigation cost a few lines and save entire account batches.
Geo consistency is the cheapest win on the list. Match timezone, locale and Accept-Language to the country of the rented port, and the mismatch that usually triggers extra verification simply disappears. Ignore it, and even a clean carrier IP starts collecting challenges.
Pro tip: verify the exit before the crawl, not after. A quick check that the IP resolves to a mobile carrier ASN with a low fraud score takes seconds and prevents a night of collecting captcha HTML into your database.
Lite or Regular for Automation
Lite is a shared device — up to five users on one port, with automatic rotation every 2–5 minutes and no manual control. It suits stateless parsing where any fresh IP will do. Regular hands over the whole device for the rental period: sticky sessions, rotation by link, timer rotation and device reboot, plus priority support.
Anything with a login belongs on Regular. A script that authenticates, waits and then continues needs the IP to hold still, and only a dedicated device guarantees that. Running a puppeteer proxy under a scheduler also benefits from reboot access — a stuck modem becomes a one-click fix rather than a lost night.
Billing is per port for 1, 7 or 30 days, with a 24-hour minimum and unlimited traffic on both plans, meaning no gigabyte counter and no surprise overage after a heavy crawl. Prices depend on country and carrier and are shown on the plan page. Cashback lands as promo credit on the internal balance after a completed rental, and refunds follow the published refund and replacement policy — full within the first hour after access is issued, otherwise minus the time used, with a replacement offered first on technical faults.
Before the First Run: Short Checklist
- One port per profile — never share an exit between accounts on the same platform.
- SOCKS5 or HTTP(S) chosen per tool: browsers and antidetect profiles prefer SOCKS5.
- Rotation link wired into retry handling, not called manually.
- Concurrency kept modest per device — a mobile channel handles a few parallel streams comfortably, not fifty.
- Carrier and city selected deliberately when the target reads geo signals.
Support runs around the clock with a 4-hour target for the first reply, so a stuck port during a release window becomes a message rather than a lost campaign. Set up the puppeteer proxy once, keep rotation in code, and the scraper stops being the fragile part of the pipeline.