Node proxy rotation

Node.js proxy rotation without fake rotation

If the HTTP client reuses the tunnel, your proxy string changed nothing.

Field notes Setup checks Updated 2026-05-16

Native fetch needs an Undici dispatcher

Node fetch is powered by Undici. Old http.Agent proxy packages do not automatically affect it. Give fetch a dispatcher built for the proxy you want to use.

import { fetch, ProxyAgent } from 'undici';
                        
                        const proxy = new ProxyAgent('http://USER:PASS@proxynade.net:2555');
                        
                        const res = await fetch('https://example.com', {
                          dispatcher: proxy
                        });
                        
                        console.log(res.status);

For hard rotation, create the dispatcher for that task and close it when the task ends. Connection pooling is useful until it hides rotation.

Axios must not fight your agent

When using custom HTTP or SOCKS agents with axios, disable axios built-in proxy parsing. Otherwise two proxy systems may try to own the same request.

import axios from 'axios';
                        import { SocksProxyAgent } from 'socks-proxy-agent';
                        
                        const agent = new SocksProxyAgent(
                          'socks5h://USER:PASS@proxynade.net:2555'
                        );
                        
                        const res = await axios.get('https://example.com', {
                          httpAgent: agent,
                          httpsAgent: agent,
                          proxy: false,
                          timeout: 30000,
                        });

Rotation strategy by job type

JobRotation choiceReason
Search result collectionRotate per query batchYou want spread, not a new IP every asset.
Account login flowSticky sessionA sudden exit change looks like a new machine.
Price monitoringRotate per domain or regionKeeps retries readable and cheap.
Blocked page retryChange proxy and slow downRetrying fast on one tunnel burns bandwidth.

Log proxy label, target host, status, bytes, and retry count together. Otherwise a failure later looks like random provider quality.

Retry loops are where bandwidth goes

Most Node scrapers waste bandwidth after the first failure. A timeout triggers a retry. The retry reloads the same heavy page. The target returns the same block. The app records zero useful rows. The proxy still counts all of it.

Use small retry budgets, block waste assets in browser jobs, and stop retrying when the response class is obviously a target block.

Use a rotation lease

A clean Node rotation setup treats each proxy assignment as a lease. The lease owns the client agent, retry budget, and labels. When the lease ends, close the agent and stop using that exit.

async function withProxyLease(proxyUrl, task) {
                          const agent = new ProxyAgent(proxyUrl);
                          try {
                            return await task(agent);
                          } finally {
                            await agent.close();
                          }
                        }
                        
                        await withProxyLease('http://USER:PASS@proxynade.net:2555', agent => {
                          return fetch('https://example.com', { dispatcher: agent });
                        });

This shape prevents a common fake rotation: one global agent, many proxy strings, and no proof that the connection changed.

Retry policy that does not burn the account

ResponseRetry?Reason
407NoAuth failed. Repeating burns time.
403Maybe once with a new leaseTarget blocked the route.
TimeoutMaybe onceCould be route or target load.
429Slow downFast retries make the signal worse.

Put this policy near the agent code. If each caller invents retries, bandwidth waste returns from another file.

Node proxy rotation FAQ

Does Node fetch use HTTP_PROXY automatically? Do not assume it. Use an explicit Undici dispatcher or an environment proxy agent you have tested.

Why does my proxy not rotate? The client may reuse the existing connection. Build rotation around task boundaries, not string assignment.

Should I use axios or fetch? Use whichever your code can instrument. The important part is clear agent ownership and retry logging.

What should I log? Proxy label, target host, status, duration, retry count, and billed GB window.