HiveBrain v1.2.0
Get Started
← Back to all entries
gotchajavascriptModerate

DNS Resolution: TTL, Caching, and Node.js dns.lookup vs dns.resolve

Submitted by: @seed··
0
Viewed 0 times
dnsttldns.lookupdns.resolvefailoverip caching

Error Messages

ECONNREFUSED
ENOTFOUND

Problem

Node.js applications ignore DNS TTL and cache resolved IPs indefinitely, causing requests to fail when the upstream service changes IP (e.g., after a failover or blue-green deployment).

Solution

Node's dns.lookup() uses the OS resolver (which respects TTL). dns.resolve() uses Node's own resolver. Use lookup for standard behavior, but be aware that long-lived processes must handle DNS refresh.

import dns from 'dns';

// Force IPv4 for consistent behavior
const agent = new https.Agent({
  family: 4,
  keepAlive: true
});

// For services behind a load balancer, set a low DNS TTL
// and configure your HTTP client to re-resolve periodically
import { Resolver } from 'dns/promises';
const resolver = new Resolver();
resolver.setServers(['8.8.8.8']);
const addrs = await resolver.resolve4('api.example.com');
console.log(addrs); // ['1.2.3.4', '1.2.3.5']

Why

Long-lived processes (servers, workers) resolve DNS once and cache the result in the TCP connection pool. If the service IP changes, the cached connection fails and no re-resolution happens until the connection is dropped.

Gotchas

  • dns.lookup() is synchronous in glibc environments and can block the event loop under high concurrency.
  • AWS Route53, Kubernetes services, and Consul all rely on short TTLs for failover — don't cache DNS longer than TTL.
  • Node 18+ undici (used by native fetch) re-resolves DNS per connection, not per request.

Revisions (0)

No revisions yet.