What TTL actually controls
A DNS record’s TTL is the number of seconds a resolver is allowed to keep your answer in its cache before it has to ask your nameservers again. That’s all it is.
Nothing in DNS is pushed. When you change a record, your authoritative nameservers start giving the new answer immediately, and every resolver that already cached the old answer keeps handing it out until its copy expires. What people call “DNS propagation” is just caches around the world expiring at different times. The worst-case delay after a change is the TTL that was in effect when each resolver cached the record, not the TTL you have now.
That one sentence explains most TTL surprises:
- If a record had a TTL of 86400 and you change the IP, some users can be stuck on the old IP for up to a day.
- If you lower that TTL to 300 and change the IP five minutes later, nothing has improved. Resolvers that cached the record before you lowered it are still holding a copy that says “good for 86400 seconds”.
- Lowering the TTL only helps after the old TTL has fully run out.
Resolvers aren’t the only caches. Operating systems, browsers and applications cache too, and not all of them respect your TTL. The JVM, for example, caches successful lookups according to its own networkaddress.cache.ttl setting rather than the record’s TTL: 30 seconds by default in OpenJDK, and forever if a security manager is installed. Long-running processes that resolve a name once at startup and reuse the connection never see your change at all until they restart.
Reading TTLs: cached vs authoritative
Ask a public resolver and you get the remaining time in its cache, counting down:
dig +noall +answer www.example.com A @8.8.8.8
www.example.com. 2793 IN A 192.0.2.10
Run it again a minute later and the number drops. Large public resolvers run many independent caches, so consecutive queries can also jump around. That’s normal.
To see the TTL you actually configured, ask one of your own nameservers directly:
dig +short NS example.com
dig +noall +answer www.example.com A @ns1.example-dns.net
www.example.com. 3600 IN A 192.0.2.10
The authoritative server always returns the full configured value. If the cached number at a public resolver is higher than the authoritative one, that resolver cached the record before you lowered the TTL, and you have to wait it out.
The DNS lookup shows the TTL each record has as public resolvers currently report it, so treat it as “time left in cache”, not your setting. The propagation check asks several public resolvers at once, which is the quickest way to see whether any of them still hold an old answer.
Values that make sense
| TTL | Seconds | When it fits |
|---|---|---|
| 1 minute | 60 | Health-checked failover, where the whole point is to switch fast |
| 5 minutes | 300 | Records you might change at short notice; the window around a migration |
| 10 minutes | 600 | A reasonable middle ground for load balancer or CDN targets |
| 1 hour | 3600 | The sensible default for A, AAAA, CNAME, TXT you don’t expect to touch |
| 4 hours | 14400 | Stable records; the default in many cPanel-hosted zones |
| 1 day | 86400 | NS records and anything that changes once a year |
My default: 3600 for ordinary web records, 300 for anything I might need to repoint during an incident, 86400 for NS. MX records can be long too, since sending servers queue and retry mail when a server is unreachable, but lower them before a mail provider change like anything else.
A TTL of 600 isn’t special. It’s ten minutes, a reasonable choice if you want changes to land within a coffee break without generating much query traffic. 14400 is four hours: fine for records that never move, painful if you discover it on the day you need to move one.
What a low TTL costs
Low TTLs are not free, and “just set everything to 60” is bad advice.
- More queries. Every expiry is another round trip to your nameservers. On providers that bill per query, such as Route 53, that is real money at scale.
- Slower cache misses. A visitor whose resolver has to go to your nameservers waits for that round trip. With a long TTL, most visitors hit a warm cache.
- Less protection during an outage. If your DNS provider goes down, records with a one-day TTL keep working from caches for hours. Records with a 60-second TTL disappear from caches within a minute. Some resolvers implement serve-stale (RFC 8767) and keep answering with expired data when they can’t reach you, but you can’t count on every resolver doing that.
Low TTLs are a tool for when you expect change. Outside those windows, longer is kinder to everyone.
Before a migration: lower, wait, change, raise
This is the one situation where TTL planning pays off directly.
- Check the current TTL at the authoritative server. Say it’s 86400.
- Lower it to 300 at least one full old TTL before the change. With 86400, that means more than 24 hours ahead. Add margin.
- Confirm the lower value is what resolvers hold. Query a few public resolvers; the counting-down TTL should now be 300 or less everywhere.
- Make the change. Within about five minutes, resolvers that respect TTLs fetch the new answer.
- Keep the old server answering for a while. Some clients ignore TTLs, as above. Leave the old host up (or redirecting) for at least a day, longer if you can.
- Raise the TTL again once you’re confident you won’t roll back. Forgetting this step is how zones end up at 300 forever.
Make sure you lower the TTL on the record that actually changes. If www is a CNAME to lb.example.net and you’re moving the load balancer, the TTL that matters is the one on lb.example.net’s address records, not the CNAME.
Maximum TTL
The TTL field is 32 bits, but RFC 2181 limits it to 2147483647 seconds (2^31 − 1), roughly 68 years, and says values with the top bit set should be treated as zero.
You’ll never get anywhere near that. Resolvers cap TTLs in their own configuration: BIND’s max-cache-ttl defaults to one week, Unbound’s cache-max-ttl to one day. DNS providers’ dashboards often stop at a day as well. In practice, a TTL above 86400 makes almost no difference and can hurt you if you ever need to change the record in a hurry.
Minimum TTL and provider floors
The protocol minimum is 0, which means “use this answer for this query and don’t cache it”. Whether you can set it depends on your DNS host:
- Cloudflare doesn’t accept less than 60 seconds on most plans (30 on Enterprise).
- Some registrar DNS panels only offer a fixed menu of values, and their lowest option may be 300 seconds or more.
- Route 53 alias records don’t take a TTL from you at all.
Resolver operators can also set a minimum cache time (Unbound’s cache-min-ttl, for example). That’s off by default, but you don’t control other people’s resolvers. Plan as if anything under 60 seconds is not guaranteed to be honoured.
Negative caching: the TTL for records that don’t exist
Resolvers cache “this name doesn’t exist” too. The time comes from your zone’s SOA record: per RFC 2308, the negative TTL is the smaller of the SOA record’s own TTL and its last field, MINIMUM.
dig +noall +answer SOA example.com
example.com. 3600 IN SOA ns1.example-dns.net. hostmaster.example.com. 2026100701 7200 3600 1209600 300
Here negative answers are cached for 300 seconds. You can see the value being applied in the authority section of a lookup for a name that doesn’t exist:
dig +noall +authority nosuch.example.com
This bites when you query a name before creating it. You test new.example.com, get NXDOMAIN, then add the record, and the resolver keeps saying “doesn’t exist” until the negative TTL runs out. The same thing happens with certificate validation records if the CA looked them up too early. Resolvers cap negative caching separately (BIND’s default max-ncache-ttl is three hours), but a large SOA MINIMUM can still cost you hours.
Records you don’t control: NS at the parent
Your nameserver delegation lives in two places. The NS records in your own zone have whatever TTL you set. The copy at the parent zone, the one the .com servers hand out, has the parent’s TTL. For .com that is two days:
dig +norecurse +noall +authority example.com NS @a.gtld-servers.net
example.com. 172800 IN NS ns1.example-dns.net.
example.com. 172800 IN NS ns2.example-dns.net.
Glue records (IP addresses for nameservers inside your own domain) come back in the same referral with the same kind of TTL. Resolvers differ in whether they keep using the parent’s delegation or switch to your zone’s NS records, so when you change DNS providers, plan for the longer of the two. Keep the old provider serving a correct copy of the zone for a few days after the switch. If your zone is DNSSEC-signed, the DS record also lives at the parent with the parent’s TTL, which matters even more when changing providers.
Cloudflare proxied records show “Auto”
When a record is proxied (orange cloud), Cloudflare answers with its own anycast addresses and the TTL shows as “Auto”, which is 300 seconds. You can’t change it.
The upside: the public answer is Cloudflare’s IPs, which don’t change when you point the record at a new origin. Changing the origin takes effect as soon as Cloudflare’s edge picks it up, with no resolver caches involved. Switching a record between proxied and DNS-only does change the public answer, so that change is subject to the five-minute TTL. For DNS-only (grey cloud) records, the TTL you set is the one resolvers get.
Related
- DNS propagation delay: why some users still see the old record and how to tell which resolvers.
- CDN cache vs DNS propagation: when the stale content isn’t DNS at all.
- Domain migration checklist: where TTL lowering fits into a full move.
Check your own domain now
Free, no sign-up. Runs the exact check this guide describes and shows what to fix.