• Print
  • Share
  • Dark

Early refresh of cache records (cache prefetch) in BIND

  • Updated on 25 Sep 2018
  • 3 minutes to read
  • Contributors

If you are having issues with performance on BIND 9.10.0 to 9.10.3, please see the article prefetch performance in BIND 9.10

A DNS resolver (recursive server) looks up information for its clients. When it finds an answer, it keeps a copy cached locally in addition to returning the answer to the requesting client. This ensures that if another request for the same information arrives, the resolver can just send another copy of the reply.

Every DNS record specifies a TTL, or Time-To-Live value. It is specified in seconds, and if that many seconds have elapsed after the record was sent from its authoritative server, clients and resolvers must delete their saved copy. If you monitor DNS traffic at a busy site, you will see TTL values ranging from a few seconds to a few days. The most common TTL values that we see range from 1 minute to 60 minutes. The authoritative server for a zone sets the TTL values; they are set by the person who administers the zone.

At the time this article was written, here are some sample TTL values selected from domains that a certain resolver was asked to look up.


The TTL for nic.cl is half a day; the TTL for akamai.com is 20 seconds. If there is a slow stream of lookup queries for nic.cl, it will expire (and thus need to be fetched again) every 12 hours. If there is a slow stream of lookup queries for akamai.com, it will need to be re-fetched every 20 seconds, which means that clients whose query arrives just after the zone has expired will not get a reply until the zone data is refreshed. This causes an uneven response rate: the response is fast if there is cached data, and slower if there is not. It can take 100x as long to re-fetch the reply to a query than it takes to return it out of the cache.

A resolver can watch the expiry times of its cached zone information, and just before a record is due to expire, the resolver can generate automatic queries to the appropriate authoritative server to fetch another copy of the record. If the record has not changed, then the only difference will be that the newly-fetched record will have a full TTL value. If the record has changed, then the updated record will be fetched. And, of course, it will also have a full TTL value.

The word "prefetch" means different things in different contexts in the world of computers, but for a DNS resolver, "prefetch" means that the resolver sometimes asks for another copy of a cached record just before its current copy is about to expire.

BIND 9.10 prefetch works as follows. There are two numbers that control it. The first number is the "eligibility". Only records that arrive with TTL values bigger than the configured elegibility will be considered for prefetch. The second number is the "trigger". If a query arrives asking for data that is cached with fewer than "trigger" seconds left before it expires, then in addition to returning that data as the reply to the query, BIND will also ask the authoritative server for a fresh copy. The intention is that the fresh copy would arrive before the existing copy expires, which ensures a uniform response time.

BIND 9.10 prefetch values are global options. You cannot ask for different prefetch behavior in different domains. Prefetch is enabled by default. To turn it off, specify a trigger value of 0. The following command specifies a trigger value of 2 seconds and an eligibility value of 9 seconds, which are the defaults.

    options {
       prefetch 2 9;

To turn off the prefetch mechanism:

    options {
       prefetch 0;

Although the benefit of prefetch is obviously greater for zones with shorter expiry times, it is less effective on zones with extremely short expiry times. That is the reason for the "eligibility" option value. The default 9-second value for eligibility is based on experimental measurements of the effectiveness of prefetch for various short-time zones.

Was this article helpful?