Node.js dns.resolve() vs dns.lookup() Node.js dns.resolve() vs dns.lookup() javascript javascript

Node.js dns.resolve() vs dns.lookup()


The dns documentation already describes the difference:

Although dns.lookup() and the various dns.resolve*()/dns.reverse() functions have the same goal of associating a network name with a network address (or vice versa), their behavior is quite different. These differences can have subtle but significant consequences on the behavior of Node.js programs.

dns.lookup()
Under the hood, dns.lookup() uses the same operating system facilities as most other programs. For instance, dns.lookup() will almost always resolve a given name the same way as the ping command. On most POSIX-like operating systems, the behavior of the dns.lookup() function can be modified by changing settings in nsswitch.conf(5) and/or resolv.conf(5), but note that changing these files will change the behavior of all other programs running on the same operating system.

Though the call to dns.lookup() will be asynchronous from JavaScript's perspective, it is implemented as a synchronous call to getaddrinfo(3) that runs on libuv's threadpool. Because libuv's threadpool has a fixed size, it means that if for whatever reason the call to getaddrinfo(3) takes a long time, other operations that could run on libuv's threadpool (such as filesystem operations) will experience degraded performance. In order to mitigate this issue, one potential solution is to increase the size of libuv's threadpool by setting the 'UV_THREADPOOL_SIZE' environment variable to a value greater than 4 (its current default value). For more information on libuv's threadpool, see the official libuv documentation.

dns.resolve(), dns.resolve*() and dns.reverse()
These functions are implemented quite differently than dns.lookup(). They do not use getaddrinfo(3) and they always perform a DNS query on the network. This network communication is always done asynchronously, and does not use libuv's threadpool.

As a result, these functions cannot have the same negative impact on other processing that happens on libuv's threadpool that dns.lookup() can have.

They do not use the same set of configuration files than what dns.lookup() uses. For instance, they do not use the configuration from /etc/hosts.

As far as concurrency goes, you are better off using dns.resolve*() because those requests do not end up in the thread pool, whereas dns.lookup() requests do because they call out to the OS DNS resolver which typically blocks (although there are some kind of-async interfaces now -- but they are not necessarily implemented everywhere).

Currently, node internally uses dns.lookup() for any automatic DNS resolution, like when you pass a hostname to http.request().


@mscdex answer is really full and explaining. I may add an info about approach we use to bypass thread blocking.

We developed a module that replaces/extends node's dns.lookup method. Module caches responses, has multi-records resolving and TTL support. Also we have good unit and functional tests with 100% coverage. Module was tested in production and highload environments. Under MIT license. Here it is: https://github.com/LCMApps/dns-lookup-cache

If you need support of lookup method but don't work negative effects like blocking of application or responses slow downs you may use our module. I believe it will help!