Configure DNS Lookup Options in Axios on Node.js
Configuring DNS lookup in Axios on Node.js allows developers to
fine-tune network performance, force specific IP versions (IPv4 or
IPv6), bypass system-level resolution limitations, and implement custom
DNS caching. Because Axios relies on the underlying Node.js
http and https modules for networking, DNS
options are configured by attaching custom http.Agent and
https.Agent instances containing custom lookup
functions to your Axios requests.
Understanding DNS Lookup in Node.js and Axios
By default, Node.js uses the operating system's
getaddrinfo system call via dns.lookup() for
domain resolution. This operates synchronously on the libuv
thread pool. Under high network traffic, this can lead to thread pool
exhaustion and increased request latency.
To modify this behavior in Axios, you define a custom
lookup option within a Node.js Agent and pass
it to your Axios instance via the httpAgent and
httpsAgent configuration properties.
Forcing IPv4 or IPv6 Resolution
A common use case is forcing Axios to resolve hostnames to IPv4 addresses to avoid timeout issues caused by broken or slow IPv6 routing on specific networks.
const axios = require('axios');
const http = require('http');
const https = require('https');
const dns = require('dns');
// Custom lookup function forcing IPv4
const ipv4Lookup = (hostname, options, callback) => {
return dns.lookup(hostname, { family: 4, all: false }, callback);
};
// Create custom agents
const httpAgent = new http.Agent({ lookup: ipv4Lookup });
const httpsAgent = new https.Agent({ lookup: ipv4Lookup });
// Create an Axios instance with the agents attached
const apiClient = axios.create({
httpAgent,
httpsAgent,
});
async function run() {
try {
const response = await apiClient.get('https://example.com');
console.log(`Status: ${response.status}`);
} catch (error) {
console.error('Request failed:', error.message);
}
}
run();Using Custom DNS Servers (Asynchronous Resolution)
If you need to query custom nameservers (such as Cloudflare
1.1.1.1 or Google 8.8.8.8) without relying on
the OS-level getaddrinfo, use the dns.Resolver
class from Node.js:
const axios = require('axios');
const https = require('https');
const { Resolver } = require('dns');
const resolver = new Resolver();
resolver.setServers(['1.1.1.1', '8.8.8.8']); // Set custom DNS servers
// Define custom lookup using the resolver
const customDnsLookup = (hostname, options, callback) => {
resolver.resolve4(hostname, (err, addresses) => {
if (err) {
return callback(err);
}
// Return the first resolved IP address and specify IPv4 family
callback(null, addresses[0], 4);
});
};
const httpsAgent = new https.Agent({ lookup: customDnsLookup });
const apiClient = axios.create({
httpsAgent,
});
async function run() {
const response = await apiClient.get('https://example.com');
console.log(response.status);
}
run();Enabling DNS Caching for High-Throughput Applications
Repeated DNS lookups for the same host add unnecessary latency. You
can install an in-memory DNS caching library like
cacheable-lookup and attach its lookup method to your Axios
agents:
npm install cacheable-lookupconst axios = require('axios');
const http = require('http');
const https = require('https');
const CacheableLookup = require('cacheable-lookup');
const cacheable = new CacheableLookup();
// Attach the cache lookup method to HTTP and HTTPS agents
const httpAgent = new http.Agent({ lookup: cacheable.lookup });
const httpsAgent = new https.Agent({ lookup: cacheable.lookup });
const apiClient = axios.create({
httpAgent,
httpsAgent,
timeout: 5000,
});
async function makeRequests() {
// First call resolves and caches the IP address
await apiClient.get('https://example.com');
// Subsequent calls use the cached IP address, bypassing DNS resolution
await apiClient.get('https://example.com');
}
makeRequests();Per-Request Configuration
If you do not want to set global agents on an Axios instance, you can
supply httpAgent and httpsAgent directly
inside the request configuration object:
await axios.get('https://example.com', {
httpsAgent: new https.Agent({
lookup: (hostname, options, callback) => {
dns.lookup(hostname, { hints: dns.ADDRCONFIG }, callback);
}
})
});