~/TechPurAI
~/tutorials/how-dns-resolution-works
intermediate·standalone·6 min read

How DNS actually works, traced step by step

Updated Aug 31, 2026Networking

DNS is invisible right up until it breaks, and then it's the first thing everyone blames and the last thing anyone actually checks. This tutorial skips the diagrams and traces a real lookup with dig, so the next time a site "isn't loading," you know exactly where to look.

The tool: dig

bash
dig example.com

dig (Domain Information Groper) sends a DNS query and prints the full response. The part that matters is the ANSWER SECTION:

text
;; ANSWER SECTION:
example.com.        86400   IN      A       93.184.216.34

That 86400 is the TTL in seconds — 24 hours — meaning any resolver that cached this answer won't ask again until it expires. That single number explains most "I changed my DNS and nothing happened" reports: the old answer is still valid and cached somewhere between you and the authoritative server.

Nobody has the full answer memorized

No single server knows what example.com points to. Instead, resolving a domain is a chain of "ask someone who knows more" hops. dig +trace shows every hop instead of just the final answer:

bash
dig +trace example.com
text
.                       IN NS   a.root-servers.net.
com.                    IN NS   a.gtld-servers.net.
example.com.            IN NS   ns1.example-dns.com.
example.com.            IN A    93.184.216.34

Read top to bottom, that's four separate servers, each pointing to the next:

  1. Root servers — don't know example.com, but know who handles .com
  2. TLD servers — don't know example.com either, but know who's authoritative for it
  3. Authoritative servers — actually hold the record and answer with the real IP

Your resolver (usually your ISP's, or 1.1.1.1 / 8.8.8.8 if you've set one manually) does this entire chain on your behalf, then caches the final answer for the TTL. This resolver is specifically called a recursive resolver — it's the one that does the multi-hop legwork. The root, TLD, and authoritative servers it talks to are never called resolvers; each of them answers a single, direct question about the piece of the hierarchy it's responsible for and nothing more.

Why this matters

When someone says "DNS is slow," this chain is what they're paying for on an uncached lookup. It's also why changing your DNS provider doesn't help a specific site load faster once the record is cached — the slowness, if real, was in this chain the first time, not in your resolver.

When the answer is "it doesn't exist"

A lookup for a domain that genuinely doesn't exist gets an NXDOMAIN response — and that gets cached too, under a separate mechanism called negative caching, controlled by the SOA record's own TTL rather than the record's:

bash
dig this-domain-should-not-exist-12345.com
text
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 12

This is why a domain that was recently registered can sometimes fail to resolve for a short window even after DNS is correctly set up — a resolver that already cached the NXDOMAIN from before the domain existed keeps serving that negative answer until its own TTL expires, independent of the new record's TTL.

Record types you'll actually touch

bash
dig example.com A       # hostname → IPv4 address
dig example.com AAAA    # hostname → IPv6 address
dig example.com CNAME   # hostname → another hostname
dig example.com MX      # domain → mail server, with priority
dig example.com TXT     # arbitrary text — SPF, domain verification, etc.

A CNAME is an alias, not an address — www.example.com pointing to example.com via CNAME means resolving www requires one more hop: look up the CNAME target, then look up that record. dig follows this chain automatically and shows both steps in the answer section.

The TTL is a promise, not a guarantee

bash
dig example.com | grep -A1 "ANSWER SECTION"

When you change a DNS record, the OLD value doesn't disappear from every cache immediately — every resolver that already has it keeps serving it until that TTL expires. A record with a 24-hour TTL that you just changed can validly return the old answer for up to 24 hours, depending on when each resolver last cached it.

Common mistake

Lowering a record's TTL the moment before you change it does nothing — resolvers are still honoring the OLD TTL for their cached copy. If you know a change is coming, lower the TTL a full TTL-period in advance, let that propagate, make the change, then raise it back once things are stable.

Checking without waiting

dig accepts @ to query a specific resolver directly, bypassing your own machine's cache entirely:

bash
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com

Querying two different public resolvers and comparing results is the fastest way to tell "my change hasn't propagated everywhere yet" (different answers) from "my change didn't actually save" (both resolvers agree, and it's wrong).

The debugging checklist

Next time something is "down" and DNS might be the cause:

bash
dig +short example.com          # what does DNS currently say?
dig +trace example.com          # where in the chain does it break?
dig @1.1.1.1 example.com        # is this specific to my resolver's cache?

+short strips everything down to just the answer — useful once you already trust the chain and just want the current value fast. Three commands, and you'll know whether the problem is DNS at all before touching anything else.

FAQ

Why doesn't lowering a TTL after I've already changed a record help? Because resolvers that cached the record before your change are honoring the old TTL on the old value — your new, lower TTL only takes effect for lookups that happen after the change, once those resolvers' existing cache entries expire naturally.

What's the difference between my resolver's cache and the browser's own DNS cache? Most browsers keep a short-lived cache of their own, separate from the OS and resolver caches — chrome://net-internals/#dns (or the equivalent in other Chromium browsers) shows and can clear it. A change that isn't showing up even after confirming the record is correct with dig @8.8.8.8 is worth checking here next.

Does every domain go through the root and TLD servers on every lookup? No — root and TLD server answers get cached too, usually for a day or longer, so a resolver that has already looked up any .com domain recently can skip straight to querying the authoritative server for a new one.

Is a CNAME the same as a redirect? No — a CNAME is resolved before your browser makes any request at all; a redirect happens after a real HTTP request reaches a server, which responds saying to try a different URL. A CNAME never involves an HTTP round trip.

VK

Vijay Kumar

Founder of TechPurAI — writing hands-on tutorials and honest tool breakdowns.

LinkedIn ↗