D. J. Bernstein
Internet publication

The dnscache program

``Today I ran some more performance tests on BIND9 and dnscache(x). Again dnscache handled a heavier load than BIND9 and handled it more gracefully. ... This dnscache box is actually a production resolver in a datacenter, and it never overloads the host or dnscache itself to do performance tests against it. Because of the ease with which dnscache handles the extra load, I now have the programs running on the big multiprocessor box use the dnscache resolver on the compaq box permanently. ... dnscache on cheaper hardware saved the day ;)'' Nate Campi, UNIX Ops WiReD SF, Terra Lycos DNS, September 2001

Sensible caching

dnscache maintains a limited-size cache of DNS information, 1 megabyte by default. When the cache fills up, dnscache smoothly discards old cache entries. It doesn't crash; like the Energizer Bunny, it keeps going, and going, and going.

In contrast, BIND keeps growing, and growing, and growing. BIND has no limits on cache size; it tries to cache every record until the record expires. Under heavy load, BIND will chew up all your physical memory, start thrashing, chew up all your virtual memory, and then commit hara-kiri, if it doesn't dump core first.

I did 968355 random PTR lookups for an Internet survey in December 1999, using alpha versions of dnsfilter and dnscache. The survey finished in 4.5 hours on a Pentium-133. In contrast, when I tried BIND instead of dnscache, BIND chewed up 32 megabytes of memory and crashed after barely more than 100000 lookups.

According to the BIND company, BIND 9 stays within a memory resource limit without crashing. Unfortunately, when the cache fills up, BIND 9 discards new cache entries. Performance drops dramatically. The server begins failing under moderate loads.

Domain server lists

You can easily configure dnscache to send queries for a particular domain to a particular set of servers, such as ``split DNS'' internal servers behind a firewall. All you have to do is put the server IP addresses into a file named after the domain. When the servers delegate a subdomain to another server, dnscache automatically contacts that server.

In contrast, BIND sends recursive queries to the servers, demanding that they act as caches and contact any relevant subdomain servers. This doesn't work with non-recursive servers, and it's a disaster for large domains. (As stated in the ``DNS and BIND'' book, third edition, pages 385-386: ``The forwarders will have an enormous query load placed on them.'') The only workaround is to change the configuration of every BIND cache on your network every time you delegate a subdomain.

Robust query handling

Sometimes, while resolving a user's query, BIND encounters a server name whose IP address it doesn't know. In this case it discards the query. It starts a background ``sysquery'' for the name, hoping to have the results cached a moment later. Consequently the user experiences a strange delay, even when the network is healthy and all servers are running smoothly.

The BIND company announced in 1995 that they were going to ``restart'' queries, eliminating this problem. Five years later, they still hadn't succeeded. ``It's too hard,'' says a comment in the BIND code. The BIND internals are too much of a mess.

dnscache doesn't have this problem. It doesn't cut corners in its resolution algorithm.