How to check dns ttl

A TTL from a caching resolver is what is left of a countdown, not the value in the zone. Read it with nslookup -debug -type=A example.com 8.8.8.8, and the same query a minute later gives a different number. Ask the zone's own nameserver for the configured value.

Checker offline. Follow the manual steps below, they give the same answer.

Why check this

Run this before you schedule a cutover and before you write any timing into a release plan. The TTL is the only number that says how long a client keeps using the old answer after you change the record. The failure it prevents is the deploy window sized from the wrong number: a team reads 90 from a resolver, plans a two-minute switch, and finds traffic still arriving at the retired host forty minutes later because the zone says 3600.

The second reason is that the TTL you read from a public resolver is an observation about that resolver's cache, not about your zone. Step 3 reads both and shows them disagreeing on the same record, in the same second.

Prerequisites

Steps

  1. Step 1.

    Read the TTL of a single answer.

    nslookup -debug -type=A example.com 8.8.8.8
    
    Got answer:
      HEADER:
    opcode = QUERY, id = 2, rcode = NOERROR
    header flags:  response, want recursion, recursion avail.
    questions = 1,  answers = 2,  authority records = 0,  additional = 0
    
      QUESTIONS:
    example.com, type = A, class = IN
      ANSWERS:
      ->  example.com
    internet address = 104.20.23.154
    ttl = 300 (5 mins)
      ->  example.com
    internet address = 172.66.147.243
    ttl = 300 (5 mins)
  2. Step 2.

    Ask the same resolver the same question six times, ten seconds apart. Save this as ttl-watch.js and run node ttl-watch.js.

    const { Resolver } = require('node:dns');
    const name = 'example.com';
    const pub = new Resolver();
    pub.setServers(['8.8.8.8']);
    const wait = (ms) => new Promise((r) => setTimeout(r, ms));
    (async () => {
      for (let i = 0; i < 6; i += 1) {
        await new Promise((done) => {
          pub.resolve4(name, { ttl: true }, (e, a) => {
            console.log(new Date().toISOString().slice(11, 19) + '  ttl=' + (e ? e.code : a[0].ttl));
            done();
          });
        });
        if (i < 5) await wait(10000);
      }
    })();
    
    20:41:18  ttl=300
    20:41:28  ttl=257
    20:41:38  ttl=300
    20:41:48  ttl=290
    20:41:58  ttl=280
    20:42:09  ttl=101

    Six identical queries, fifty seconds, six different numbers, and the sequence goes up as well as down. 8.8.8.8 is one address served by many machines, each holding its own copy of the answer with its own age. Each reply is the remainder on whichever machine took the query.

  3. Step 3.

    Read the resolver and the zone's own nameserver in one run. Save this as ttl-compare.js and run node ttl-compare.js example.com hera.ns.cloudflare.com.

    const { Resolver } = require('node:dns');
    const [name, authNs] = process.argv.slice(2);
    const pub = new Resolver();
    pub.setServers(['8.8.8.8']);
    const read = (res, label) =>
      new Promise((done) => {
        res.resolve4(name, { ttl: true }, (e, a) => {
          const t = new Date().toISOString().slice(11, 19);
          console.log(`${t}  ${label.padEnd(18)} ${e ? e.code : a.map((v) => `${v.address} ttl=${v.ttl}`).join('  ')}`);
          done();
        });
      });
    const wait = (ms) => new Promise((r) => setTimeout(r, ms));
    (async () => {
      await read(pub, '8.8.8.8');
      await wait(20000);
      await read(pub, '8.8.8.8');
      await wait(20000);
      await read(pub, '8.8.8.8');
      const ip = await new Promise((d) => pub.resolve4(authNs, (e, a) => d(a[0])));
      const auth = new Resolver();
      auth.setServers([ip]);
      await read(auth, authNs);
    })();
    
    20:40:26  8.8.8.8            172.66.147.243 ttl=300  104.20.23.154 ttl=300
    20:40:46  8.8.8.8            104.20.23.154 ttl=300  172.66.147.243 ttl=300
    20:41:06  8.8.8.8            104.20.23.154 ttl=163  172.66.147.243 ttl=163
    20:41:06  hera.ns.cloudflare.com 104.20.23.154 ttl=300  172.66.147.243 ttl=300

    The last two lines are one second apart on the same record. The cache says 163, the zone says 300. 300 is the number to plan against, because it is the longest any resolver can hold this answer.

  4. Step 4.

    Read the same value on Windows without Node.

    Resolve-DnsName example.com -Type A -Server 8.8.8.8 | Format-Table Name,Type,TTL,IPAddress -AutoSize
    
    Name        Type TTL IPAddress
    ----        ---- --- ---------
    example.com    A 300 104.20.23.154
    example.com    A 300 172.66.147.243

    -Server sends the query to the named resolver and bypasses the Windows resolver cache, so the number is the remote cache's remainder. Drop -Server and the number comes from the local cache instead.

How to read the result

| What you see | What it means | What to do | | --- | --- | --- | | The configured maximum, such as ttl = 300 | The resolver had no copy and fetched a fresh one | Treat this as the zone's value, and confirm against the nameserver | | A smaller number such as 163 | The remainder of a countdown on the machine that answered | Plan against the configured value, never against this | | The number rises between two reads | A different machine behind the same anycast address replied | Stop treating repeated reads as one cache | | The authoritative server returns the same number every time | That is the configured TTL. It does not count down | Size the cutover window from it | | Non-existent domain with no TTL shown | A negative answer, cached under the SOA minimum, not the record TTL | Read the SOA to find how long the absence is held |

Common mistakes

Sign: A runbook records the TTL from one lookup and treats it as the zone setting.Cause: Step 3 read 163 from 8.8.8.8 and 300 from the zone's own nameserver one second apart. A resolver reports the time left on its copy. Only a query to an authoritative server returns the configured value, and that value is the one a cutover has to wait out.
Sign: A script polls the resolver until the TTL reaches zero and then declares the cache clear.Cause: It will not reach zero, and the poll never terminates. Step 2 shows the value climbing from 257 back to 300 between consecutive reads, because a large public resolver is many independent caches behind one address. There is no single countdown to observe.
Sign: The TTL is lowered to 60 an hour before a cutover and old answers persist for the rest of the day.Cause: Lowering a TTL does not shorten copies that are already cached. A resolver that fetched the record just before the change holds it for the old duration. The short value has to be published at least one old TTL ahead of the change, not an hour ahead of it.

What to check next

FAQ

How to check dns ttl nslookup shows by default?

It does not show one. Plain nslookup prints names and addresses only. Add -debug and the TTL appears on each record in the answer section, as in step 1. -d2 prints the request packet as well.

How to check dns ttl value in windows?

Resolve-DnsName example.com -Type A -Server 8.8.8.8 has a TTL column, as in step 4. For the copy held on the machine itself, Get-DnsClientCache -Entry example.com prints a TimeToLive that counts down in real time.

How to check dns record ttl for a type other than A?

Change the type and read the same field: nslookup -debug -type=MX example.com 8.8.8.8, or Resolve-DnsName example.com -Type MX. Each record type at a name carries its own TTL, and they are often different.

Which number do I plan a cutover against?

The value an authoritative nameserver returns, because that is the longest any resolver is allowed to hold the answer. Add the time it takes your provider to publish an edit, and treat clients that ignore TTLs as a separate problem.

Verified

Verified by Maks Vernynslookup Windows 11 build 22631node 22.23.2PowerShell 5.1

Each output block is what the command above it printed on that date, on the host named in the step. Figures read from a live site move between runs. Compare the shape of the answer rather than the digits, and see the methodology for how a page is re-verified.

intermediate7 minpublished updated Maks Verny