Undici Proxy Setup
Undici is Node.js's built-in HTTP client (powering the global `fetch` in Node 18+) and the fastest HTTP/1.1 client available for Node.js. Its dispatcher architecture makes proxy integration clean and composable — you create a ProxyAgent once and pass it as the dispatcher for any request. Undici handles the CONNECT tunnel, keep-alive, and connection pooling through the proxy automatically.
Basic Configuration
const proxyUrl = \`http://\${process.env.PROXY_USER}:\${process.env.PROXY_PASS}@gate.hexproxies.com:8080\`; const proxyAgent = new ProxyAgent(proxyUrl);
const { statusCode, body } = await request('https://httpbin.org/ip', { dispatcher: proxyAgent, headers: { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', }, });
const data = await body.json(); console.log(statusCode, data); ```
Using with Node.js Global Fetch
Node 18+ includes a global `fetch` powered by Undici. You can route it through a proxy by setting the global dispatcher:
const proxyAgent = new ProxyAgent({ uri: \`http://\${process.env.PROXY_USER}:\${process.env.PROXY_PASS}@gate.hexproxies.com:8080\`, keepAliveTimeout: 30000, keepAliveMaxTimeout: 60000, connections: 20, });
setGlobalDispatcher(proxyAgent);
// All global fetch calls now route through the proxy const res = await fetch('https://example.com'); console.log(await res.text()); ```
Connection Pooling and Performance
Undici's ProxyAgent maintains a connection pool to the proxy gateway. Configure the pool size to match your proxy plan's concurrency limit:
const proxyAgent = new ProxyAgent({
uri: proxyUrl,
connections: 50, // max concurrent connections to proxy
pipelining: 1, // requests per connection (1 for proxy compatibility)
keepAliveTimeout: 10000, // ms to keep idle connections alive
});Common Pitfalls
The most common mistake is creating a new ProxyAgent for every request. Each agent allocates a connection pool — creating hundreds of agents wastes memory and prevents connection reuse. Always create one agent and share it across requests.
Another subtle issue: Undici's default request timeout is 30 seconds. Residential proxies add 200-500ms latency per request. For large pages or slow targets, increase the timeout:
const { body } = await request(url, {
dispatcher: proxyAgent,
headersTimeout: 15000,
bodyTimeout: 30000,
});Retry Logic for Proxy Errors
Undici does not retry failed requests automatically. Implement retry logic with exponential backoff for proxy connection resets and 429 responses. Distinguish between proxy-layer failures (retry immediately) and target-layer blocks (backoff before retrying).
IP Rotation
For per-request IP rotation, generate a unique session ID and embed it in the proxy username. Create a new ProxyAgent per session group, or use the Hex Proxies gateway's automatic rotation mode where each new connection gets a fresh IP.