🍱 Lunchbox Hands

dns

DNS Propagation Is Not Real: What You Are Actually Waiting For

Nothing "propagates" when you change a DNS record — millions of independent resolver caches just expire on their own schedules. Where the 24–48 hour folklore comes from, the TTL procedure that removes the wait, and why lookups made too early keep failing.

You update an A record, your registrar’s help page tells you to “allow 24–48 hours for DNS propagation,” and you settle in to wait for your change to spread across the internet like ink in water. Except that’s not what’s happening, because DNS propagation does not exist: nothing is pushed anywhere, no wave sweeps the globe — you are waiting for millions of independent caches to hit their expiry timers, each on its own schedule. Once you see the actual mechanism, the 24–48 hour figure turns out to be folklore with one very specific grain of truth in it, and most of the waiting turns out to be optional.

This is the same species of comfortable myth as “blurring redacts text” — a mental model that survives because it’s easy to picture, not because it’s true. So let’s replace the picture.

What actually happens when you change a record

When you edit DNS, you’re editing the zone on your authoritative name servers — the handful of machines your domain delegates to. That’s the entire “publish” step. Nobody notifies the world’s resolvers. There is no registry of caches to update, no broadcast, no propagation protocol.

Everyone else — the recursive resolvers run by ISPs, Google, Cloudflare, your office router — operates on a pull model. RFC 1034 (the 1987 spec that defines DNS concepts) describes it plainly: copies of data “are distributed with timeouts for refreshing,” and the recipient is responsible for performing the refresh. Every record carries a TTL, a 32-bit count of seconds that, per the same RFC, “describes how long a RR can be cached before it should be discarded.” (A TTL of zero prohibits caching entirely.)

So the lifecycle of your change is:

  1. A resolver looked up example.com at some point and cached the answer, stamped with your TTL.
  2. You change the record. The resolver neither knows nor cares.
  3. The resolver keeps serving its cached copy until the timer runs out.
  4. On the next query after expiry, it asks your authoritative servers and gets the new value.

That’s it. “Propagation time” is just the maximum age of the stalest cache that matters to you — which is your TTL, not a property of the internet.

Why you and your friend see different sites

During the TTL window, disagreement isn’t an error — it’s the mechanism, mid-flight. Each resolver network cached your record at a different moment, so each one’s timer expires at a different moment:

ObserverResolverCached the old record atSees the new value at
You, at homeISP resolver09:58 (TTL 3600)~10:58
Your friend1.1.1.1 (nearest Cloudflare PoP)never queried itimmediately
Your phone on LTECarrier resolver09:15~10:15
A user in another citySame ISP, different cache node10:01~11:01

Two details make this messier than the table suggests. First, big public resolvers are anycast: 8.8.8.8 is one IP answered by data centers worldwide, and each data center runs its own cache — so “Google has my new record” is really “the Google cache nearest that particular user does.” Second, resolvers cache per record type, so your new A record and your unchanged MX record are on completely independent timers.

None of this is broken. For one TTL-length window, part of the internet correctly serves the old answer and part correctly serves the new one.

Where the “24–48 hours” folklore comes from

If propagation is just TTL expiry, why does every registrar quote two days? Because there is one DNS change where two days is genuinely the worst case — and support pages long ago flattened everything into that number.

The slow case is changing your name servers — moving the domain from one DNS provider to another. Your NS delegation doesn’t live only in your zone; the parent TLD’s servers publish their own copy of it, along with glue addresses, and you don’t control the TTL on those records. Ask the .com servers directly and you can see it:

$ dig @a.gtld-servers.net example.com NS +norecurse +noall +authority

example.com.   172800   IN   NS   hera.ns.cloudflare.com.
example.com.   172800   IN   NS   elliott.ns.cloudflare.com.

172,800 seconds — exactly 48 hours, on both the NS records and their glue. A resolver that cached your old delegation moments before the switch can keep sending every query to your old DNS provider for up to two days, and no setting in your control panel changes that. Combine that hard 48-hour ceiling with the day-long TTLs that were common on ordinary records in DNS’s early decades, and you get the number that registrar boilerplate has recited ever since.

But notice what the folklore quietly does: it applies the worst case of the rarest change to every change. Editing an A, CNAME, MX, or TXT record at your existing DNS provider never touches the parent’s delegation. That change converges in one TTL — often five minutes.

ChangeWho controls the relevant TTLRealistic worst case
A / AAAA / CNAME / MX / TXT editYouOne TTL (minutes to hours)
Adding a brand-new recordYou (via SOA — see below)One negative TTL
Switching name serversThe TLD registryUp to 48h (.com NS TTL: 172800s)

Practical corollary for migrations: since you can’t shorten the delegation TTL, serve identical zones from both old and new providers during the handover. Then it doesn’t matter which side a resolver asks. You can confirm which name servers the registry has on file with a WHOIS lookup — that’s registry data, not zone data, as we covered in WHOIS is now RDAP.

The procedure that removes the wait

Since the wait is just the old TTL playing out, you can shrink it in advance:

Day 0:        A record, TTL 86400  →  lower TTL to 300. Change nothing else.
Day 1 (≥24h): every cache now holds a copy stamped TTL=300
Day 1:        make the actual change
Day 1 +5min:  the internet has converged
Later:        raise TTL back to 3600–86400

The step everyone skips is the middle one: you must wait out the old TTL before the change, because resolvers that cached the record before your TTL edit are still holding day-long copies — lowering the TTL doesn’t reach into their caches. The short TTL only takes effect once those old entries have expired and been re-fetched.

And restore the TTL afterward. A permanently short TTL buys you nothing but extra query load on every lookup, forever, plus less resilience if your authoritative servers have an outage.

Negative caching: why the record you just added “isn’t propagating”

There’s a mirror-image trap that catches people creating new records: “this name doesn’t exist” is also a cacheable answer. RFC 2308 defines negative caching — when a resolver gets an NXDOMAIN, it caches that non-existence, with a TTL taken from “the minimum of the SOA.MINIMUM field and SOA’s TTL” of your zone.

The failure mode: you’re about to add app.example.com, and you helpfully test it first to confirm it doesn’t exist yet. Your resolver dutifully caches the NXDOMAIN. Then you create the record — and your machine keeps insisting the name doesn’t exist until the negative TTL expires, while everyone who didn’t pre-test sees it instantly. It looks exactly like slow propagation; it’s actually a self-inflicted cache entry.

The rule: never look up a name before you’ve created its record. (And keep your SOA’s negative TTL modest — RFC 2308 itself notes values of one to three hours work well and anything over a day is problematic.)

”Flush your DNS” fixes exactly one machine

ipconfig /flushdns, sudo dscacheutil -flushcache, restarting the browser — all real, all useful, and all strictly local. They empty your stub cache so your machine re-asks its resolver. They do nothing for the resolver’s own cache, let alone the other few million resolvers on earth. Flushing your DNS to speed up propagation is turning your own monitor off and on to fix a website.

There are exactly two caches you can legitimately reach beyond your machine, because both big public resolvers offer public flush tools:

  • Google Public DNS: dns.google/cache — flushes a domain/type pair across their resolvers (captcha-gated, rate-limited).
  • Cloudflare 1.1.1.1: one.one.one.one/purge-cache — same idea: enter the domain, pick the record type, purge.

Genuinely worth doing after a botched change. But they cover two resolver networks out of millions; every ISP resolver still runs out its clock.

Resolvers that don’t take your TTL literally

One honest complication: the TTL is an instruction, not a law of physics, and some resolvers edit it. The best-documented case is Google Public DNS, whose own FAQ notes that cached record TTLs “are generally limited to six hours even if the actual TTL is longer” — a ceiling, which works in your favor: a forgotten 86400 TTL still converges on Google within ~6 hours. Working against you, some ISP resolvers and OS-level caches enforce minimum TTLs, quietly holding your 60-second record for longer than you asked. So a handful of stragglers after your window has passed doesn’t mean you did anything wrong — it means someone else’s cache policy is overriding your number.

Watching the caches expire, honestly

Since “propagation” is really a population of caches in various states of expiry, the way to observe it is to ask several independent caches the same question and compare. That’s exactly what our DNS propagation checker does: it queries four independent public resolver networks — Google (8.8.8.8), Cloudflare (1.1.1.1), DNS.SB, and AliDNS — over DNS-over-HTTPS straight from your browser, plus a fifth lookup through our own Cloudflare Worker, in parallel, for A, AAAA, CNAME, MX, TXT, or NS records. When every reachable network agrees, you get a green banner; while they’re mixed, the TTL column shows each straggler’s maximum remaining wait — the longest it may serve its current answer before it must re-fetch — which tells you precisely when to hit Re-check.

The honest caveat, which applies to every propagation checker including the ones with world maps: sampling a handful of resolver networks can never prove that every cache on earth has expired. It shows you the networks most of your visitors actually use, and — via the TTLs — bounds the worst case for the ones it can see. That’s the strongest claim any checker can truthfully make.

When one specific resolver is misbehaving and you want its full answer — SOA serials, CAA, the works — point DNS Lookup at the domain instead. And if you’re unsure which record type you even changed, start with DNS record types explained.

The short version

The folklore saysThe mechanism says
”Changes propagate across the internet”Nothing moves; caches independently expire per RFC 1034’s TTL
”Allow 24–48 hours”One TTL for record edits; 48h only for name-server changes (TLD NS TTL: 172800s)
“Some regions get it before others”Different resolvers cached at different moments; geography is incidental
”Flush your DNS to speed it up”Fixes your machine only — though Google and Cloudflare offer real per-domain flush tools
”My new record isn’t propagating”You looked it up too early and cached the NXDOMAIN (RFC 2308)
“Set a low TTL and forget it”Lower before a change, wait out the old TTL, change, then restore

And if the record you’re waiting on is an MX, there’s a second layer of folklore stacked on top of this one: a valid email address is not a deliverable one covers what an MX lookup does and doesn’t prove about mail actually arriving.