You are about to change the address a hostname points to. What does the TTL actually promise you, and why do clients keep reaching the old address anyway?
A TTL is an upper bound on how long a resolver may cache a record, not a promise about when clients will notice a change. Lowering it only takes effect after one old TTL has elapsed, negative answers are cached under a different rule, and pooled connections keep using an address they resolved hours ago.
What the interviewer is scoring
- Whether the TTL is described as an upper bound resolvers may shorten rather than as a guarantee
- Does the candidate get the arithmetic right, that a TTL reduction only bites after one old TTL has expired
- That caches below the recursive resolver are named, including the application runtime and connection pools
- Whether negative caching is distinguished from positive caching and traced to the SOA record
- Can they say what a TTL buys you at all when the authoritative servers are unreachable
Answer
What the number means and who is bound by it
The TTL travels with the record from your authoritative nameserver and tells any cache how many seconds it may keep the answer. That is the whole contract, and note its direction: it is permission to cache for up to that long, not an instruction to cache for exactly that long and not a promise about anything else. A resolver is free to cache for less, and resolvers do impose their own floors and ceilings, so a 30-second TTL is a request that a large public resolver may honour and a small enterprise resolver may not.
More importantly, the TTL says nothing about clients. It governs the resolver's cache, and between the resolver and the socket there are several more caches that answer to different rules, which is why "we set the TTL to 300 so it will switch over in five minutes" is wrong in almost every direction at once.
The arithmetic people get backwards
Suppose the record has carried a TTL of 86400 for years and you plan to move the address tomorrow morning. You lower the TTL to 300 an hour beforehand. That does nothing for any resolver that already has the answer, because it is holding a copy stamped with 86400 seconds of validity and it will not ask again until that expires. It may serve the old address for the rest of the day.
The rule is that a TTL reduction only takes effect after one full old TTL has elapsed, so you have to lower it at least 86400 seconds before the change and leave it low. Then, after the switch, wait out the low TTL before restoring the original value, because raising it early re-arms long caching against the old answer for any resolver that happens to refresh in that window. Sequenced properly, a move with a day-long TTL needs planning to begin two days ahead, and being able to state that ordering is the difference between having read about TTLs and having done a migration.
The caches the TTL does not reach
Below the recursive resolver the picture gets less obedient. Operating-system stub resolvers cache, and on Linux that depends on whether something like systemd-resolved is in the path, while on Windows the DNS Client service keeps its own cache; each has its own rules and its own flush command. Browsers keep a cache of their own. Runtimes cache too, and the case worth naming is the JDK, where successful and failed lookups are cached inside the InetAddress layer for durations controlled by the networkaddress.cache.ttl and networkaddress.cache.negative.ttl security properties rather than by your zone's TTL. A long-lived server process configured to cache addresses aggressively will ignore your migration entirely.
Then there is the cache that is not a cache. An established TCP connection holds a peer address, not a hostname, so every pooled and keep-alive connection continues to the old machine until it is closed, regardless of what DNS now says. A connection pool that resolves once at connect time and keeps connections for hours is the usual reason one client still reaches the old address long after everybody else has moved. That is also the reason the old address must keep working through the migration: you are waiting for connections to drain, not for DNS.
Negative answers cached under a different rule
If a query is made before the record exists, the resolver caches the absence. How long is governed not by the record's TTL, which does not exist yet, but by the zone's SOA — the negative-caching rule of RFC 2308 — and it is entirely possible for that to be far longer than the positive TTL you carefully set. Creating a new hostname, discovering somebody probed it a minute too early, and then waiting out a negative cache you never configured is one of the most common self-inflicted delays in this area. Set the SOA minimum deliberately before you add records people are waiting for.
When the TTL is irrelevant because nobody can reach your nameservers
In October 2021, a configuration change withdrew the BGP routes advertising Facebook's DNS servers, so their names stopped resolving worldwide, and the internal tooling needed to reverse the change depended on the same network. This is the layered dependency that networking questions are really about: routing, name resolution and management access looked like three independent systems and turned out to be one. When you design for recovery, say which control path survives the failure it exists to repair.
The TTL's role in that shape is worth being precise about. While cached entries are still valid, resolvers keep answering and the damage is invisible; once they expire, there is nowhere to ask and resolution fails outright. A short TTL, chosen to make failover fast, therefore shortens the grace period you get when your own nameservers become unreachable. RFC 8767 lets a resolver serve stale data past its TTL when it cannot reach the authoritative servers, which softens this, but it is a resolver-side behaviour you do not control and cannot rely on. The design conclusion is the unglamorous one: keep the authoritative nameservers reachable by paths that do not depend on the thing they are needed to fix, and spread them across networks that fail separately.
The TTL is an upper bound on the resolver's cache, not a switchover time. Lower it a full old TTL before the change, keep the old address serving until pooled connections drain, and remember that a short TTL also shortens the only grace period you get if your nameservers ever become unreachable.
Likely follow-ups
- How would you move traffic with no DNS change at all, and when is that the better option?
- Why is changing which nameservers serve a zone slower to take effect than changing an address inside it?
- Resolution now returns the new address but one client still reaches the old one. Where do you look?
- What recovery time can DNS-based failover honestly promise, and what would you use if you needed seconds?
Related questions
- How do you handle cache invalidation, and what goes wrong at scale?hardAlso on caching5 min
- What goes into a cache key, and what happens when two requests that should get different responses collide on one?hardAlso on caching6 min
- Your application cannot reach a service that should be up. Walk me through diagnosing it from the shell.mediumAlso on dns6 min
- Walk me through everything that happens when you type a URL into the browser and press enter.mediumAlso on dns6 min
- You cached something in a module-level dictionary. It works on your laptop and behaves oddly in production. What is different?mediumAlso on caching5 min
- When does a decorator actually run, and what goes wrong when you stack two of them?mediumAlso on caching4 min
- Which status codes and method semantics do you insist on in a code review, how do the caching headers fit together, and is the API you just described REST?mediumAlso on caching5 min
- Design the asset delivery and deploy strategy for a large single-page app. What happens to a user who has the tab open when you ship?hardAlso on caching6 min