Articles › Servers and DevOps

Why does my new site still show the old one? DNS caching and TTL, a real case

We pointed a domain at a new server, yet Google's resolver answered the old IP for two more hours. Why, how to see what each layer sees, and how to move without the wait.

Beginner 7 min read October 21, 2026

What you will learn
  • DNS does not "propagate" anywhere; everyone who asked earlier keeps the old answer until its TTL runs out
  • The maximum wait equals the OLD record's TTL, not 48 hours. Lower the TTL to 300 s a day before the move
  • Check one layer at a time with dig or nslookup, asking the real nameserver and 8.8.8.8, then compare
  • Request the TLS certificate only after public DNS sees the new IP, not after your own machine does

On 16 October we moved a domain (mykaset.com) from its old host to a server of our own. We updated the A record at DigitalOcean, and asking ns1.digitalocean.com directly returned the new IP immediately. Asking Google’s 8.8.8.8, though, still returned the old IP for about 2 hours 20 minutes. People on Google DNS kept seeing the old site while everyone else saw the new one. Here is why, how to see what each layer sees, and how to move next time without the wait.

Commands were tested on Windows 11 and Ubuntu 24.04. On Ubuntu dig comes with the dnsutils package (sudo apt install dnsutils); on Windows use nslookup, or Resolve-DnsName in PowerShell.

Where one lookup travels

Type a site name into the browser and the question “what IP is this name?” passes through these layers, and every layer has its own cache.

LayerRun byWhere the answer is kept
BrowserChrome, Firefoxthe browser’s own cache
Operating systemWindows, Linuxthe DNS client cache
Resolveryour ISP, Google 8.8.8.8, Cloudflare 1.1.1.1a cache shared by millions of users
Authoritative nameserverthe domain’s DNS provider, e.g. DigitalOceanno cache; this is the source

A layer holding an unexpired answer replies on the spot without asking the next one. That is why the web is fast, and also why an old site lingers.

Browser / operating systemkeeps answers for a whileYour ISP's resolver or 8.8.8.8keeps the OLD answer until its TTL endsAuthoritative nameserveryour DNS provider's; changes at onceeveryone sees the new answer once the old TTL expires
The source changes at once; the caching layers hold the old answer until the TTL ends

TTL is the answer’s expiry date

Every record carries a TTL (time to live) in seconds, telling whoever receives the answer how long they may keep it. Here is this site’s own record, asked straight from the authoritative server:

# Ubuntu 24.04
dig +noall +answer 6amdev.com @ns1.digitalocean.com
# 6amdev.com.   3600   IN   A   157.x.x.x

3600 is the full TTL. Ask a resolver that has already answered this question and the number is lower, because it is counting down:

dig +noall +answer 6amdev.com @8.8.8.8
# 6amdev.com.   2299   IN   A   157.x.x.x    <- 2299 s left before it asks the source again

The key point: the TTL that governs your wait is the OLD record’s TTL, the one others cached before you made the change, not the value you just set. A resolver holding the old copy has no idea you changed anything until its own counter reaches zero.

A worked example: TTL 3600

  • The old A record has TTL 3600. You change it to the new IP at 10:00.
  • Resolver A asked at 09:59. It keeps answering the old IP until 10:59, then re-asks and gets the new one.
  • Resolver B asked at 09:20. It switches at 10:20.
  • Resolver C has never seen this name. It asks at 10:01 and gets the new IP straight away.

So in the worst case the last cached old answer expires no more than 60 minutes after the change, not 48 hours. The “48 hours” figure comes from changing nameservers at the registrar, where NS records often carry TTLs of a day or more, and from a few resolvers that simply ignore TTL.

Different people see different sites not because DNS “hasn’t propagated yet”, but because each person uses a different resolver, and each resolver last asked the source at a different moment.

For mykaset.com we had not lowered the TTL beforehand, and the old host’s record carried a long one, so 8.8.8.8 held the stale value for over two hours while resolvers that had never seen the name picked up the new IP at once.

Why to lower the TTL before the move, not during it

Changing the TTL from 3600 to 300 and the IP in the same minute achieves nothing: everyone holding the old copy holds it with the old 3600 attached. The right order is:

  1. A day before the move, lower the TTL on the records you will change to 300 seconds (the IP stays old).
  2. Wait for the old copies to expire everywhere (one full old TTL; if it was 86400 you really do wait a day).
  3. On moving day, change the IP. Everyone sees the new value within 5 minutes.
  4. Once the new site is stable, raise the TTL back to 3600 to spare the nameservers.

Checking what each layer sees

Ask the source first. If the source does not return the new value, the change did not land, and caching is not your problem.

# Ubuntu 24.04: the source and the public resolvers
dig +short NS mykaset.com                       # who the nameservers are
dig +short mykaset.com @ns1.digitalocean.com    # the source
dig +short mykaset.com @8.8.8.8                 # Google
dig +short mykaset.com @1.1.1.1                 # Cloudflare
dig +short mykaset.com                          # the resolver this machine actually uses
# Windows 11 (PowerShell)
nslookup mykaset.com ns1.digitalocean.com
nslookup mykaset.com 8.8.8.8
Resolve-DnsName mykaset.com -Type A -Server 8.8.8.8   # also shows the remaining TTL

If the source is right but your machine still sees the old site, flush the layer nearest to you first:

ipconfig /flushdns                 # Windows: OS cache
sudo resolvectl flush-caches       # Ubuntu 24.04 (systemd-resolved)

Chrome keeps one more cache of its own: open chrome://net-internals/#dns and click Clear host cache. If you have done all that and still see the old site, the stale copy lives in a resolver you do not own. You can wait, point your machine at a different resolver for a while, or, if the stale one is Google’s, use their flush tool at dns.google/cache: enter the domain and record type and press Flush. That is what we did; 8.8.8.8 returned the new IP immediately afterwards. Cloudflare has an equivalent Purge Cache page at one.one.one.one/purge-cache. Each tool clears only its own resolver; people on their ISP’s DNS still have to wait.

certbot looks at public DNS too, not at your machine

When you request a certificate with HTTP-01, Let’s Encrypt resolves the domain from several places around the world (its primary datacenter plus several remote perspectives, and a quorum must agree), then fetches the challenge file from http://your-domain/.well-known/acme-challenge/. If any of those vantage points still gets the old IP, it knocks on the old host, finds no file, and the challenge fails. Fail a few times in a row and you hit the rate limits.

Our site-adding script therefore checks DNS before every certbot run, asking the real nameserver rather than the machine’s resolver:

# Ubuntu 24.04: stop if the source does not point at this machine yet
MY_IP=$(curl -s https://api.ipify.org)
NS=$(dig +short NS "$DOMAIN" | head -1)
DNS_IP=$(dig +short "$DOMAIN" @"$NS" | tail -1)
[ "$DNS_IP" = "$MY_IP" ] || { echo "DNS still points at $DNS_IP, not $MY_IP; wait"; exit 1; }

Passing that gate, you should still check @8.8.8.8 and @1.1.1.1 once more before the real request, because Let’s Encrypt goes through public DNS just like everyone else. Or use DNS-01 instead, which needs nobody to reach your server at all.

Domain-move checklist

  • A day before: lower the TTL on the A/AAAA and CNAME records you will change to 300
  • New server ready; test it via the hosts file or curl --resolve mykaset.com:80:NEW_IP http://mykaset.com/
  • Moving day: change the IP at the nameserver, then dig @ns1... to confirm the source is right
  • Wait until @8.8.8.8 and @1.1.1.1 return the new value; if one is stuck, flush it at dns.google/cache
  • Only now run certbot (HTTP-01), or use DNS-01
  • Leave the old host running for at least one old TTL; do not switch it off the same day
  • Once stable, raise the TTL back to 3600

Common mistakes

  • Checking from your own machine and calling it done. You may see the new site while customers do not, or the other way round. Always ask the source and the public resolvers.
  • Switching the old host off immediately. Anyone still getting the old IP sees an error instead of the old site.
  • Forgetting the hosts file entry after testing, then wondering why you see something different from everyone else.
  • Lowering the TTL and changing the IP in one go, which helps nobody, as explained above.

Sources

FAQ

I moved my site and still see the old one. How long do I wait?

At most the TTL of the old record, counted from the moment you changed it. With TTL 3600 that is 60 minutes. To see how long is left, ask the resolver that still returns the old value with dig and read the TTL column in the answer; it counts down.

Why does my friend see the new site while I still see the old one?

Different resolvers. Your friend's resolver may never have asked for this name before, so it fetched the new value straight away; yours asked before the move and still remembers the old one. Flush your own machine first; if that does not help, the stale copy is at the resolver, so wait or switch resolvers temporarily.

What is the hosts file good for here?

Put the domain and the new IP in your machine's hosts file and the browser skips DNS entirely, which is a good way to test the new server before the move. Remove the line afterwards, or you will keep seeing something different from everyone else.

Commands and settings were tested on sample systems. Try them on a test machine before production.