
What is DNS caching and why does it matter?
DNS caching is the practice of storing the answer to a DNS lookup for a set period of time, so the next request for the same name can be answered immediately instead of being looked up again from scratch. Caches exist in your browser, your operating system, your router, and above all in the recursive resolver run by your ISP or a public DNS service. Each cached answer is kept for the record's TTL (time to live), set by the domain owner. Caching matters because it makes browsing fast, keeps load off the authoritative nameservers, and lets the internet keep working during short outages, but it is also the reason DNS changes don't take effect everywhere at once.
Almost every DNS question you will ever debug, from "why is my new site not showing?" to "why does this outage seem to affect only some users?", comes back to caching. In this article you'll learn how DNS caching works at each layer, how a cached answer ages, how to inspect the caches on your own machine and on a resolver, how caching helps and hurts, and how to plan changes around it.
How a DNS Lookup Uses Caches
A full DNS lookup without any caching involves several round trips. To resolve www.example.com, a resolver would need to ask a root server where .com lives, ask a .com server where example.com lives, and then ask the authoritative nameserver for example.com for the actual record. Each of those steps can take tens of milliseconds, sometimes far more if a server is far away.
Caching short-circuits that work. When an answer is cached, the lookup stops at the first layer that has a valid copy. The usual order on a typical laptop is:
- Application or browser cache: Chrome, Firefox and other browsers keep their own short-lived DNS cache.
- Operating system cache: The stub resolver built into Windows, macOS or Linux keeps answers for every application on the machine.
- Local network cache: Many home routers and office firewalls run a caching forwarder such as dnsmasq.
- Recursive resolver cache: Your ISP's resolver, or a public resolver such as 1.1.1.1, 8.8.8.8 or 9.9.9.9, holds a large shared cache for all its users.
- Authoritative nameserver: Only if nothing above has a valid copy does a query reach the servers that actually host the zone.
The recursive resolver cache is the most important of these. It is shared by thousands or millions of users, so a single popular name like www.google.com might be looked up from the authoritative servers once and then served from cache to everyone for the rest of the TTL.
Resolvers Cache More Than Final Answers
A recursive resolver doesn't just cache the final A record. It also caches every piece of the path it learned along the way:
- The NS records for
.comand the IP addresses of those servers. - The NS records for
example.comand the addresses of its nameservers. - Any CNAME records followed while resolving the name.
- Negative answers, meaning "this name does not exist" or "this name has no record of this type".
This is why a busy resolver rarely talks to the root servers. It already knows where every common TLD lives, and that knowledge is cached for days.
How Cached Answers Age
Every DNS record carries a TTL in seconds. When a resolver caches a record, it starts counting that TTL down. When the count reaches zero, the entry expires and the next query triggers a fresh lookup.
You can watch this happen with dig. Query the same resolver twice, a few seconds apart:
dig @1.1.1.1 example.com A +noall +answer
example.com. 3247 IN A 192.0.2.10
Wait about ten seconds and run it again:
example.com. 3237 IN A 192.0.2.10
The TTL in the second answer is ten seconds lower. The resolver is serving the same cached entry and telling you how much life it has left. Ask the authoritative nameserver directly and you'll always see the full configured value, because authoritative servers don't cache their own zones:
dig @ns1.example.com example.com A +noall +answer
example.com. 3600 IN A 192.0.2.10
Comparing these two numbers is one of the quickest ways to tell whether an answer came from cache.
Every Resolver Has Its Own Clock
There's no global cache. Each resolver caches independently, starting from whenever it first looked up the name. If you change a record, a resolver that cached it 59 minutes ago will refresh within a minute, while one that cached it 30 seconds ago will keep serving the old value for almost the full TTL. That's why changes appear to roll out gradually and unevenly.
Large public resolvers also run many separate cache nodes in different locations, and the node you reach may differ from one query to the next. You may see two different TTLs, or even two different answers, from the same resolver IP during a change.
Caching on Your Own Machine
The operating system and browser caches are usually small and short-lived, but they're the first thing to check when your machine disagrees with everyone else.
Windows
Windows runs the DNS Client service, which caches answers for all applications. You can view the cache in PowerShell:
Get-DnsClientCache | Where-Object Entry -like "*example.com*" |
Format-Table Entry, RecordType, TimeToLive, Data -AutoSize
Entry RecordType TimeToLive Data
----- ---------- ---------- ----
example.com A 3180 192.0.2.10
www.example.com CNAME 3180 example.com
The older command ipconfig /displaydns shows the same information in a longer text format.
macOS
macOS caches DNS in the mDNSResponder process. There's no simple built-in command to print its cache, but you can see which resolvers macOS is using, and therefore where cache misses will go, with:
scutil --dns | grep nameserver
nameserver[0] : 192.168.1.1
nameserver[1] : 2001:db8:1::1
Linux
Many modern distributions use systemd-resolved, which includes a local cache. You can check its cache statistics:
resolvectl statistics
Transactions
Current Transactions: 0
Total Transactions: 18421
Cache
Current Cache Size: 214
Cache Hits: 11032
Cache Misses: 7389
A high ratio of hits to misses shows the local cache is doing useful work. Not every Linux system caches locally, though. Minimal servers and containers often send every query straight to the resolver listed in /etc/resolv.conf.
Browsers
Chrome and other Chromium-based browsers keep an internal host cache, viewable at chrome://net-internals/#dns. Browsers cap their own cache times at a minute or so, so they rarely cause long-lasting stale answers on their own, but they can hold onto an old address just long enough to confuse a quick test.
Caching in a Recursive Resolver
If you run your own resolver, you can see and control exactly how it caches. Unbound is a common choice, and its cache can be inspected with unbound-control:
sudo unbound-control lookup example.com
The following name servers are used for lookup of example.com.
;rrset 86398 2 0 2 0
example.com. 86398 IN NS a.iana-servers.net.
example.com. 86398 IN NS b.iana-servers.net.
To see a specific cached record set, you can dump the cache and search it:
sudo unbound-control dump_cache | grep -A1 "^example.com"
Unbound also lets you tune caching behaviour in unbound.conf:
server:
# Cache sizes
msg-cache-size: 64m
rrset-cache-size: 128m
# Never cache for longer than one day, regardless of the record's TTL
cache-max-ttl: 86400
# Serve expired answers if the authoritative servers can't be reached
serve-expired: yes
serve-expired-ttl: 86400
# Refresh popular records shortly before they expire
prefetch: yes
A few of these settings deserve explanation:
- cache-max-ttl caps how long any record is held. Most resolvers apply a cap like this, so a record published with a one-week TTL may still be refreshed daily.
- cache-min-ttl forces a minimum cache time. It's tempting to raise it to reduce traffic, but it means ignoring the domain owner's TTL, which can break failover and migrations. Leave it at the default of zero unless you have a strong reason.
- prefetch tells Unbound to refresh records that are still being requested when they're close to expiry, so popular names rarely suffer a cache miss.
- serve-expired implements "serve stale" behaviour, described in RFC 8767. If the authoritative servers are down when a record expires, the resolver keeps answering with the old data for a while rather than returning an error.
To clear a single name from Unbound's cache, for example after a change:
sudo unbound-control flush example.com
Why DNS Caching Matters
Caching is not a side feature of DNS. The whole system depends on it.
Speed
A cache hit at the resolver usually returns in a few milliseconds, while a full uncached lookup can take 50 to 300 milliseconds or more. Because every new connection to a new hostname needs a DNS answer, and modern web pages pull resources from many hostnames, those savings add up quickly.
You can see the difference in dig's timing line. The first query for a less popular name is a cache miss:
;; Query time: 142 msec
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)
Repeat it immediately and it's served from cache:
;; Query time: 4 msec
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)
Scale
Without caching, the root and TLD servers would receive every lookup on the internet. Caching reduces that to a trickle of refreshes. Your own authoritative nameservers benefit in the same way: a site with millions of visitors may see only a small fraction of that number in DNS queries, because resolvers answer most of them from cache.
Resilience
Cached answers keep working even when the authoritative servers don't. If your DNS provider has a short outage, users whose resolvers already cached your records can still reach your site until those entries expire. With serve-stale enabled, many resolvers will keep using the old data even beyond the TTL while the outage lasts. Longer TTLs give you a bigger buffer here.
Privacy and Cost
Every cache hit is a query that doesn't leave the resolver, so fewer parties see it. For organisations that pay per query on their authoritative DNS, such as some cloud DNS services, caching also directly reduces the bill.
The Downside: Stale Answers
The same mechanism that makes DNS fast also makes it slow to change. When you update a record, every cache that already holds the old value keeps serving it until its copy expires. This causes several familiar problems:
- Website moves look half-finished: Some visitors reach the new server while others still reach the old one.
- Email continues to arrive at the old mail server: If MX records change, sending servers may use the cached value for a while.
- Failover is delayed: If you switch traffic away from a failed server by changing DNS, clients keep connecting to the dead address until their cached entry expires.
- Records you just created seem missing: If you looked up a name before creating it, resolvers may have cached the "does not exist" answer and keep returning it for a while.
That last case surprises many people. A resolver caches negative answers for a period derived from the zone's SOA record, so testing a new hostname before you've created it can make you wait longer to see it. A good habit is to create records first and test them afterwards.
Applications That Cache on Their Own
Some software ignores TTLs altogether. Older Java versions could cache successful lookups indefinitely when a security manager was installed, and long-running processes such as connection pools, proxies and database clients often resolve a hostname once at startup and never again. If a service keeps talking to an old IP address long after the TTL has passed, check whether the application itself is holding onto it. Restarting the process often confirms the diagnosis.
Working With Caching When You Make Changes
You can't flush caches you don't control, but you can plan for them.
- Lower the TTL in advance: A day or two before a planned change, lower the TTL on the records you'll change, for example to 300 seconds. Wait for the old TTL to expire so caches pick up the short one.
- Make the change: Update the record. Most resolvers will now pick up the new value within five minutes.
- Keep the old target running: Leave the old server or mail host online until traffic to it stops.
- Raise the TTL again: Once you're happy, set the TTL back to a longer value to regain the speed and resilience benefits.
For your own testing, you can bypass your local caches by querying the authoritative nameserver directly:
# Find the authoritative nameservers
dig example.com NS +short
ns1.example.com.
ns2.example.com.
# Ask one of them directly, bypassing every cache
dig @ns1.example.com www.example.com A +short
203.0.113.25
If the authoritative server returns the new value but your browser still shows the old site, the change is correct and you're simply waiting for caches to expire.
A Simple Script to Compare Cached Answers
When you're watching a change roll out, it helps to compare what several public resolvers are returning, along with their remaining TTLs. This small Python script uses the dnspython library (pip install dnspython):
import dns.resolver
NAME = "www.example.com"
RECORD_TYPE = "A"
RESOLVERS = {
"Cloudflare": "1.1.1.1",
"Google": "8.8.8.8",
"Quad9": "9.9.9.9",
}
for label, ip in RESOLVERS.items():
resolver = dns.resolver.Resolver(configure=False)
resolver.nameservers = [ip]
try:
answer = resolver.resolve(NAME, RECORD_TYPE)
values = ", ".join(r.to_text() for r in answer)
print(f"{label:<11} TTL {answer.rrset.ttl:>6} {values}")
except dns.resolver.NXDOMAIN:
print(f"{label:<11} NXDOMAIN")
except Exception as exc:
print(f"{label:<11} error: {exc}")
Sample output during a migration might look like this:
Cloudflare TTL 212 203.0.113.25
Google TTL 2874 192.0.2.10
Quad9 TTL 41 203.0.113.25
Here Google's resolver still has the old address cached with nearly 48 minutes left, while the other two have already picked up the new one.
FAQ: DNS Caching
DNS answers can be cached in your browser, your operating system, your router or firewall, and the recursive resolver run by your ISP or a public DNS service. The recursive resolver's cache has the biggest effect because it is shared by many users.
Up to the record's TTL, which the domain owner sets in seconds. Many resolvers also apply their own maximum, often around one day, and browsers usually keep entries for only a minute or so.
No. You can only flush caches you control, such as your own computer or your own resolver. Some public resolvers, including Cloudflare and Google, offer a web page where you can request a cache purge for a specific name.
Yes, in both directions. Caching reduces how often queries travel across the network, but a poisoned cache entry would affect every user of that resolver until it expires. DNSSEC validation protects resolvers from caching forged answers.
Something between you and the authoritative nameserver still has the old answer cached. Query the authoritative nameserver directly with dig to confirm the change is live, then wait for the old TTL to expire or flush your local caches.
Yes. If a name or record type doesn't exist, resolvers cache that fact for a time based on the zone's SOA record. Creating a record after someone has already looked it up can mean a short wait before it appears.
No. Disabling caching would make every lookup slower and put heavy load on DNS servers. Use short TTLs on records you expect to change, and lower them in advance of planned migrations instead.
Conclusion
DNS caching is what makes the Domain Name System fast enough to use. Browsers, operating systems, routers and especially recursive resolvers keep copies of answers for the length of each record's TTL, which cuts lookup times to a few milliseconds, protects authoritative servers from overwhelming load, and keeps sites reachable during brief DNS outages.
The trade-off is that changes are never instant. Treat the TTL as a promise about how long the old answer may live, lower it before planned changes, test against the authoritative servers directly, and remember that negative answers and badly behaved applications can cache too. Once you think about DNS in terms of caches, most "propagation" mysteries become easy to explain.


