You changed a DNS record, the new address is live, and half the world still visits the old one. That is not a ghost. That is the TTL.
The short answer
The TTL (time to live) of a DNS record is a number of seconds that says how long the record may be cached before the source of the information should be asked again [1]. Resolvers and caches along the way keep the answer until that time runs out, so a change shows up gradually, not at once [1][5]. Our assessment: lower the TTL a while before a planned change, change the record, and raise the TTL again afterwards.
How it works
- A countdown. The zone keeps a constant TTL for each record, while cached copies count down. When the countdown ends, the data is expired and should be ignored [1]. A zero TTL means the record may only be used for the transaction in progress and must not be cached [1].
- Range and meaning. RFC 2181 settled what STD 13 left unclear: a TTL is an unsigned number from 0 to 2147483647, which is 2^31 − 1 seconds. It says that the TTL specifies a maximum time to live, not a mandatory one, so a cache may set its own upper bound [2].
- One TTL per record set. All records of one set, such as several A records for the same name, must have the same TTL [2].
- Practice caps it. RFC 8767 recommends capping TTLs on the order of days to weeks, with 604,800 seconds (7 days) as the recommended cap [4].
- Serve stale. The same RFC lets a resolver use expired data when it cannot reach the authoritative servers to refresh it. Such stale records are returned with a TTL of 30 seconds, and the suggested maximum stale time is 1 to 3 days [4].
- Negative answers have a TTL, too. For "name does not exist" and "no data of that type", the TTL comes from the SOA record, as the minimum of its MINIMUM field and its own TTL [3]. Create a record that was just queried and missed, and some caches keep saying "does not exist" for that long. Our reading of RFC 2308.
- Vendors set limits. At Cloudflare, proxied records always use "Auto", which is 300 seconds. For DNS-only records you can choose between 60 seconds (30 seconds on Enterprise) and 1 day. Cloudflare adds that your local DNS cache may need longer than five minutes to show a change [5].
- Look at it. The tool
digprints the TTL of each record by default, and+noall +answerlimits the output to the answer section [6].
A practical example
A record for nas.example.com has a TTL of 3600 seconds (one hour). You plan to move the service to a new address next Saturday. On Friday you lower the TTL to 300 seconds, and you leave at least the old TTL, one hour, before the move, because a resolver that asked just before the change may hold the old answer that long. On Saturday you change the address. Later you raise the TTL back. Ask your resolver twice a few seconds apart and watch the TTL shrink [1][6]:
dig +noall +answer nas.example.comWe have not documented our own DNS records in our inventory (14 to 16 Oct 2026), so the names and numbers here are invented for illustration.
Checklist
- Lower the TTL at least one old TTL before the change, and lower it first, not at the same time [1][2].
- Remember that some caches and clients set their own limits, and a TTL is a maximum [2][4].
- Expect old answers after an outage, because resolvers may serve stale data [4].
- Check the SOA values if "does not exist" lingers after you add a record [3].
- Use a short TTL only where you need it, because longer TTLs make lookups faster, and raise it again after the move [5].
- Test with
dig, and flush your local cache before you decide the change failed [5][6].