DNS Resolution: The Full Picture
How domain resolution actually works — from root servers through TLD nameservers to your browser. The hierarchy, record types, response codes, zone files, and why DNS queries are nearly invisible.
DNS is a hierarchical, distributed database that turns names into numbers. You type example.com, and somewhere between your keyboard and a TCP connection opening, a chain of servers conspires to produce 93.184.216.34. This guide covers every layer of that process — the hierarchy, the resolution walk, the record types, the response codes, the wire format, and the zone files that make it all work.
The Hierarchy
Every domain name resolution walks down a tree. The tree has exactly three levels that matter:
. (root) | ┌───────────┼───────────┐ com net org ← TLD (Top-Level Domain) | | | example example example ← Second-Level Domain (SLD) | www ← Subdomain / hostEach node in the tree has its own set of authoritative nameservers — servers that are the final source of truth for records at that level. The root knows about TLDs. TLD servers know about second-level domains. Authoritative nameservers know about everything under their domain.
Root servers
There are 13 root server identities, named a.root-servers.net through m.root-servers.net, operated by 12 organizations (Verisign operates two). Through anycast routing, those 13 identities map to over 1,700 physical instances worldwide. A query to a.root-servers.net from Tokyo hits a different machine than the same query from London, but both return the same answer.
Root servers answer exactly one question: “Who is authoritative for this TLD?” They don’t know about example.com. They know that .com is handled by Verisign’s a.gtld-servers.net through m.gtld-servers.net.
TLD nameservers
Each TLD has its own set of nameservers operated by the registry. For .com, that’s Verisign. For .org, that’s Public Interest Registry. For .de, that’s DENIC.
TLD nameservers answer: “Who is authoritative for this second-level domain?” They store NS (nameserver) records pointing to each registered domain’s authoritative nameservers. This is essentially the content of the zone file.
Authoritative nameservers
The final stop. These are the nameservers set by the domain owner (or their hosting provider). They hold the actual records — A records, MX records, CNAME records, everything. When Cloudflare or AWS Route 53 “hosts your DNS,” they’re running your authoritative nameservers.
Resolution Walk-Through
When you look up example.com, your resolver performs an iterative walk down the hierarchy. Here’s the full sequence:
1. Client → Recursive resolver: "What is example.com?"2. Resolver → Root server: "Who handles .com?" Root → Resolver: "Ask a.gtld-servers.net (Verisign)"3. Resolver → TLD server: "Who handles example.com?" TLD → Resolver: "Ask ns1.example.com at 93.184.216.34"4. Resolver → Authoritative NS: "What is example.com?" Auth NS → Resolver: "A record: 93.184.216.34"5. Resolver → Client: "93.184.216.34"Three actors make this work:
Recursive resolver — does the full walk for you. This is 1.1.1.1 (Cloudflare), 8.8.8.8 (Google), or whatever your ISP provides. When you configure DNS settings on your machine, you’re choosing your recursive resolver. It caches aggressively — after the first lookup, it knows who handles .com for hours.
TLD nameserver — operated by the registry (e.g., Verisign for .com). Contains NS records for every registered domain under that TLD. The .com TLD servers know about all ~160 million .com domains.
Authoritative nameserver — the final source of truth for a domain’s records. Set by the domain owner or their hosting provider. This is where your A record, MX record, and everything else actually lives.
Why it feels instant
In practice, steps 2 and 3 are almost always cached. Your recursive resolver already knows who handles .com (the TTL on root-to-TLD delegations is 48 hours). It probably has the NS records for popular domains cached too. The typical cold lookup takes 50-100ms. A warm lookup (fully cached) takes under 5ms.
What dig shows you
You can watch this process with dig:
# Full recursive trace — shows each stepdig +trace example.com
# Ask a specific resolverdig @1.1.1.1 example.com A
# Ask an authoritative server directlydig @ns1.example.com example.com A +norecurse
# Query for NS records (who handles this domain?)dig example.com NS
# Get the SOA record (zone metadata)dig example.com SOAThe +trace flag is particularly instructive. It starts at the root and follows each delegation, showing you exactly which server returned what. The output reads like a conversation between your machine and the hierarchy.
Record Types That Matter
DNS has dozens of record types. Seven of them cover nearly everything you’ll encounter:
| Type | Purpose | Example | TTL range |
|---|---|---|---|
| A | IPv4 address | example.com → 93.184.216.34 | 60s – 86400s |
| AAAA | IPv6 address | example.com → 2606:2800:220:1:248:1893:25c8:1946 | 60s – 86400s |
| NS | Nameserver delegation | example.com → ns1.example.com | 3600s – 172800s |
| SOA | Start of Authority (zone metadata) | Serial number, refresh intervals | 3600s – 86400s |
| MX | Mail server (with priority) | 10 mail.example.com | 3600s – 86400s |
| CNAME | Alias to another name | www.example.com → example.com | 60s – 86400s |
| TXT | Arbitrary text data | SPF records, domain verification tokens | 300s – 86400s |
A and AAAA
The workhorses. An A record maps a name to an IPv4 address. AAAA does the same for IPv6. A domain can have multiple A records (round-robin load balancing) and both A and AAAA records simultaneously (dual-stack).
NS
Nameserver records define delegation. The NS records in the .com zone for example.com point to ns1.example.com and ns2.example.com. These are what the TLD server returns in step 3 of the resolution walk. Without NS records, a domain can be registered but won’t resolve — it’s not in the zone.
SOA
Every zone has exactly one SOA (Start of Authority) record. It contains the primary nameserver name, the responsible party’s email (encoded as a DNS name), a serial number that increments on changes, and timing parameters for zone transfers. The serial number is how secondary nameservers know when to pull updates.
MX
Mail exchange records have a priority value (lower = preferred) and a target hostname. When sending email to [email protected], the sender’s mail server queries the MX records for example.com and connects to the lowest-priority server that responds. Multiple MX records with different priorities provide failover.
CNAME
A canonical name record is an alias. www.example.com CNAME example.com means “look up example.com instead.” CNAMEs can’t coexist with other record types at the same name — a name is either a CNAME or it has direct records, never both. This constraint trips people up regularly (you can’t put a CNAME at the zone apex because SOA and NS records must exist there).
TXT
Free-form text records. Originally meant for human-readable notes, now heavily used for machine-readable data: SPF records for email authentication (v=spf1 include:_spf.google.com ~all), DKIM public keys, domain verification tokens for Google/Microsoft/Cloudflare, and DMARC policies. A single domain commonly has 5-10 TXT records.
Response Codes
Every DNS response includes a 4-bit response code (RCODE) in the header. Four codes matter in practice:
| Code | Name | Meaning | What it tells you |
|---|---|---|---|
| 0 | NOERROR | Name exists, records returned | The domain resolves. Records are in the answer section. |
| 3 | NXDOMAIN | Name does not exist | The authoritative server for this zone has no record of this name. For a query against a TLD server, this means no registrar has placed the domain in the zone. |
| 2 | SERVFAIL | Server failure | The resolver couldn’t complete the query. Could be a timeout talking to an upstream server, a DNSSEC validation failure, or a misconfigured zone. Retry with a different resolver. |
| 5 | REFUSED | Policy refusal | The server declined to answer. Usually means you’re querying a server that doesn’t serve that zone, or an authoritative server that doesn’t allow recursive queries. Try a different server. |
NXDOMAIN is the most interesting signal. When a TLD nameserver returns NXDOMAIN for example.com, it means no delegation exists — no registrar has placed NS records for that name in the zone. This is the fastest possible way to determine that a domain doesn’t resolve (a single UDP round-trip to the TLD server).
The caveat: A domain can be registered but absent from the zone. Domains in serverHold or clientHold status, domains with no nameservers configured, and domains in redemptionPeriod are all registered but return NXDOMAIN. An NXDOMAIN response tells you the domain isn’t in the zone — not that it’s unregistered.
DNS over HTTPS (DoH)
Traditional DNS uses UDP on port 53, unencrypted. Every query and response travels in plaintext. Your ISP can see every domain you look up. Any network middlebox can intercept and modify responses.
DNS over HTTPS wraps DNS queries inside standard HTTPS requests. From a network perspective, DoH traffic is indistinguishable from normal web browsing — it’s TLS-encrypted traffic on port 443.
Cloudflare DoH
curl -s "https://cloudflare-dns.com/dns-query?name=example.com&type=A" \ -H "Accept: application/dns-json" | jq .Response:
{ "Status": 0, "TC": false, "RD": true, "RA": true, "AD": true, "CD": false, "Question": [ { "name": "example.com", "type": 1 } ], "Answer": [ { "name": "example.com", "type": 1, "TTL": 3600, "data": "93.184.216.34" } ]}The fields in the response map directly to DNS header flags: Status is the RCODE (0 = NOERROR), TC is Truncated, RD is Recursion Desired, RA is Recursion Available, AD is Authenticated Data (DNSSEC validated), and CD is Checking Disabled.
For a non-existent domain, Status would be 3 (NXDOMAIN) and the Answer array would be empty.
Google DoH
curl -s "https://dns.google/resolve?name=example.com&type=A" | jq .Same JSON structure with minor field name differences. Both services support type=A, type=AAAA, type=NS, type=MX, type=TXT, and any other valid record type.
Why DoH matters
Three reasons, in order of practical importance:
-
Privacy: Your DNS queries are encrypted. Your ISP (and anyone else on the network path) can’t see which domains you’re looking up. They can see you’re talking to
cloudflare-dns.com, but not what you’re asking. -
Integrity: HTTPS provides authenticity. A network middlebox can’t inject forged DNS responses (a technique used by some ISPs to redirect failed lookups to ad pages and by some governments for censorship).
-
Convenience: JSON responses are trivial to parse in any language. No DNS library needed — any HTTP client works. This makes DNS lookups accessible from environments where raw UDP isn’t available (browsers, serverless functions, restricted networks).
The tradeoff is latency. A raw UDP DNS query to 1.1.1.1 completes in ~10ms. A DoH query adds TLS handshake overhead on the first request (~50ms total), though subsequent queries reuse the connection.
DNS Query Anatomy
A DNS query is remarkably small. When dig sends a query, it constructs a single UDP datagram:
┌──────────────────────────────────────────┐│ Header (12 bytes) ││ - Transaction ID: random 16-bit ││ - Flags: RD=1 (recursion desired) ││ - Question count: 1 │├──────────────────────────────────────────┤│ Question section ││ - Name: example.com (variable length) ││ - Type: A (or AAAA, NS, MX, etc.) ││ - Class: IN (Internet) │├──────────────────────────────────────────┤│ EDNS(0) OPT record (optional, ~11 bytes) ││ - UDP payload size: 4096 ││ - DNSSEC OK (DO) flag: 0 or 1 ││ - DNS Cookie (optional) │└──────────────────────────────────────────┘Total: ~40–80 bytes. Single UDP datagram.That’s the entire request. No TLS handshake. No HTTP framing. No headers. No User-Agent. No Accept-Language. No cookies. The response is similarly compact — a single UDP datagram back.
The fingerprint surface comparison
This matters if you care about privacy or anonymity. Compare what a DNS query reveals about the sender versus what an HTTPS request reveals:
What a DNS query exposes:
| Element | Typical values | Identifiability |
|---|---|---|
| Source IP | Your IP or proxy IP | Primary identifier |
| EDNS buffer size | 4096 (dig), 1232 (newer default), 512 (legacy) | Minor signal |
| DNSSEC OK flag | 0 or 1 | Negligible |
| DNS Cookie | Present or absent | Negligible |
| Transaction ID | Random 16-bit | Expected to vary |
| RD (Recursion Desired) | Almost always 1 | Universal — not distinguishing |
What an HTTPS request exposes:
TLS version, 15+ cipher suites in a specific order, 20+ TLS extensions with GREASE values, HTTP/2 SETTINGS frame, WINDOW_UPDATE size, HEADERS frame priority, 12+ HTTP headers in a specific order, User-Agent string, Accept-Language, Sec-Ch-Ua (browser brand/version), Sec-Ch-Ua-Platform, Sec-Fetch-Site, Sec-Fetch-Mode, cookie jar, and more.
DNS queries are effectively anonymous except for the source IP. The protocol simply doesn’t carry enough metadata to fingerprint the client. This is a fundamental property of UDP-based protocols with fixed, minimal headers — there’s no room for the kind of feature negotiation that makes TLS and HTTP so fingerprintable.
Zone Files
A zone file is a text file that describes a DNS zone — the complete set of records that an authoritative nameserver serves. For a TLD like .com, the zone file is the master list: every registered domain that has nameserver delegations.
BIND format
Zone files use BIND format (named after the Berkeley Internet Name Daemon, the most widely deployed DNS server software). Here’s a simplified view of what the .com zone file looks like:
; .com zone file (simplified)$ORIGIN com.$TTL 172800
; SOA record — zone metadatacom. IN SOA a.gtld-servers.net. nstld.verisign-grs.com. ( 1710000000 ; serial (increments on each update) 1800 ; refresh (30 min) 900 ; retry (15 min) 604800 ; expire (7 days) 86400 ) ; minimum TTL (1 day)
; TLD nameserverscom. IN NS a.gtld-servers.net.com. IN NS b.gtld-servers.net.; ... 11 more
; Domain delegations — one block per registered domainexample.com. IN NS ns1.example.com.example.com. IN NS ns2.example.com.; Glue records (needed when NS is under the delegated domain)ns1.example.com. IN A 93.184.216.34ns2.example.com. IN A 93.184.216.34
google.com. IN NS ns1.google.com.google.com. IN NS ns2.google.com.; ... ~160 million more entriesThe $ORIGIN directive sets the default suffix. The $TTL directive sets the default time-to-live for records. Lines starting with ; are comments. The SOA record’s serial number is the version — secondary nameservers compare their serial to the primary’s and pull a zone transfer (AXFR or IXFR) when it’s behind.
Glue records deserve a note. When example.com delegates to ns1.example.com, there’s a circular dependency — you need to resolve ns1.example.com to find the nameserver for example.com, but ns1.example.com is under example.com. Glue records break the cycle by embedding the A record for the nameserver directly in the parent zone.
Scale
The .com zone file contains approximately 160 million domain delegations. Compressed with gzip, it’s roughly 4-5 GB. Uncompressed: 15-20 GB. Verisign regenerates it multiple times per day.
ICANN’s Centralized Zone Data Service (CZDS) provides access to TLD zone files for approved purposes. You apply at czds.icann.org, each TLD registry reviews independently, and once approved you get API access for programmatic daily downloads.
What zone files don’t contain
Zone files are a subset of the registry database. They contain only domains that are active and have nameserver delegations. Missing from the zone:
- Domains in
serverHoldorclientHoldstatus (suspended by registry or registrar) - Domains in
pendingDeletestatus (queued for deletion) - Domains in
redemptionPeriod(expired, recoverable at penalty cost) - Domains registered but with no nameservers configured
- Registrant or contact information
- Registration and expiry dates
This distinction matters. A domain that returns NXDOMAIN in DNS could be registered but held, suspended, or in a grace period. The zone file reflects what resolves, not what’s registered.
Zone file diffing
Because zone files are regenerated daily, comparing consecutive snapshots reveals domains entering and leaving the zone:
Day 1 zone: {example.com, test.com, mydomain.com, ...}Day 2 zone: {example.com, test.com, ...}
Diff: mydomain.com disappeared from the zoneA domain disappearing from the zone could mean:
- It entered
pendingDelete— will be fully deleted in 5 days - It was placed on
serverHoldorclientHold— still registered, just suspended - Its nameservers were removed — still registered, just not delegated
- It entered
redemptionPeriod— might become available in 30-35 days
The zone file tells you what changed. To understand why, you need to query the registry’s RDAP service, where the domain’s status flags reveal its actual state.
Putting It Together
DNS resolution is elegant because each layer knows only what it needs to. Root servers know TLDs. TLD servers know second-level domains. Authoritative servers know records. No single server has to know everything, and the caching at every level means the system handles billions of queries per day with response times measured in milliseconds.
The key things to remember:
- The hierarchy is strict: root, TLD, authoritative. Three levels. Always.
- Recursive resolvers do the work: your machine asks once; the resolver walks the tree.
- Caching makes it fast: TTL values control how long each answer stays cached.
- NXDOMAIN means “not in the zone”: it doesn’t always mean “not registered.”
- DNS queries are tiny: 40-80 bytes, single UDP datagram, near-zero fingerprint surface.
- Zone files are the ground truth: what’s in the zone is what resolves. Everything else is metadata stored elsewhere.
The protocol is 40 years old (RFC 1035, November 1987) and still handles the internet’s naming layer with minimal changes to its core design. The extensions — DNSSEC, DoH, DoT, EDNS — are layers on top, not replacements. The hierarchy and the delegation model are the same ones Paul Mockapetris designed in 1983.