How DNS turns names into addresses
Open in the interactive app: practice, quiz, mock interview →In one minute
- DNS is a delegated, cached database. The root delegates
com,comdelegatesexample.com, and a recursive resolver walks those referrals once and then caches every step: answers, aliases, delegations and "does not exist". - TTL is your change-propagation budget. You choose it per record, ahead of time: an answer you published yesterday with a one-day TTL cannot be recalled today.
- Every service you run depends on two DNS systems you must design for: the authoritative side (your zones, your provider) and the resolver side (the caches your clients and your own fleet use).
- GeoDNS and health-checked failover steer resolvers, not users, and converge in minutes. They are good for choosing a region, poor for anything faster.
- DNS failures are rare but total: when names stop resolving, every dependency fails at once, so redundancy and stale-serving matter more than raw speed.
How it works
Delegation: who is authoritative
A zone is a slice of the name tree run by one operator. The parent holds NS records naming the child's nameservers, plus glue addresses when those nameservers live inside the child zone. The child holds its own NS, SOA and data. The registrar only puts your NS records into the TLD zone. If the parent points at a server that no longer serves the zone (a lame delegation), resolvers waste timeouts on it, and changing providers means changing parent NS records that com publishes with a two-day TTL.
What a resolver caches
A recursive resolver (Unbound, BIND, a cloud resolver, 1.1.1.1) caches four kinds of state, each with its own TTL:
- Answers for a name and type, such as the
Arecords ofwww.example.com. - Aliases (
CNAME), followed and cached link by link. - Delegations: which servers are authoritative for
comandexample.com. This is why a warm resolver almost never asks a root server. - Negative answers:
NXDOMAIN(name does not exist) or NODATA (name exists, type does not), cached for the minimum of theSOArecord's last field and the SOA TTL (RFC 2308).
Record types that shape designs
CNAME hands a hostname to a CDN or load balancer, but cannot sit at the zone apex next to SOA and NS; providers work around that with ALIAS records or "CNAME flattening". TXT carries ownership proofs (ACME DNS-01, SPF), CAA lists which CAs may issue for the domain, SRV gives host, port and weight for service discovery, and HTTPS records advertise protocols such as h3 before the first connection (RFC 9460).
TTL strategy
TTLs are a trade between agility and cost. Sensible defaults: NS and delegations at one to two days, stable A records at 5 to 60 minutes, records you may fail over at 30 to 60 seconds, and a negative TTL of a few minutes. Planned changes follow a pattern: lower the TTL to 60 seconds at least one old TTL before the change, make the change, verify, then raise it again. Lowering the TTL at the moment of the change does nothing for answers already cached under the old one.
Steering and failover
The authoritative server can answer per query by resolver location (GeoDNS), by the EDNS Client Subnet, by weight, or by health checks that remove dead endpoints. It sees the resolver's address, not the user's, and caching sets the limits (Google SRE book, ch. 19): one resolver fronts many users, some resolvers enforce minimum TTLs, client libraries cache on their own, and open connections never re-resolve. The DNS Load Balancing lesson covers the policies; remember that DNS failover takes minutes and its tail hours.
Resolvers inside your own fleet
Every process has a stub resolver (glibc's, configured by /etc/resolv.conf) that forwards to a recursive resolver. Its defaults matter at scale. Kubernetes sets ndots:5 and several search domains (Kubernetes DNS), so a lookup of api.stripe.com (two dots) first tries api.stripe.com.default.svc.cluster.local and two other suffixes, each for A and AAAA: eight queries instead of two. A node-local cache (NodeLocal DNSCache) or a trailing dot on external names (api.stripe.com.) removes most of that load.
Down the stack
Layer 1The contract
A resolver promises an answer that was true at the authority within the past TTL seconds, and carries no version, so stale looks exactly like current. NXDOMAIN is an authoritative "does not exist" and is cached; SERVFAIL means the resolver failed and is cached only briefly. With serve-stale (RFC 8767), a resolver that cannot reach any authority may return expired data, up to one to three days old, with a 30-second TTL. Nothing orders updates across names: a client may see one name's new record and another's old one.
Layer 2The mechanism
A referral is a response with an empty answer section, the child's NS records in the authority section and glue in the additional section, without the AA (authoritative answer) bit. The resolver algorithm (RFC 1034, section 5.3.3) is: look in the cache for the answer; otherwise find the closest ancestor zone whose delegation is cached, query one of its servers, and repeat on each referral until an authoritative answer or NXDOMAIN. Unbound keeps an infrastructure cache of each nameserver's smoothed round-trip time and prefers the fastest, and with prefetch: yes it refreshes popular entries when less than 10% of their TTL remains, so hot names never expire under load, at the cost of about 10% more upstream traffic (Unbound docs). QNAME minimisation (RFC 9156) sends each ancestor only the next label, so the root learns com, not your full hostname. DNSSEC adds RRSIG signatures over record sets, DNSKEY records for zone keys, and DS records in the parent that chain trust from the root.
Layer 3The machine
A query is one UDP datagram of 40 to 80 bytes; a cache hit in the same data centre returns in well under a millisecond, a cold recursive walk takes 50 to 200 ms. Answers too big for the size the client advertised in EDNS come back truncated (the TC bit set), and the client retries over TCP, which every general-purpose DNS implementation must support (RFC 7766). Since DNS Flag Day 2020 the recommended EDNS buffer is 1,232 bytes, the IPv6 minimum MTU minus headers, so answers never rely on IP fragmentation, which is unreliable and easier to spoof (DNS Flag Day 2020). Large DNSSEC answers therefore move to TCP more often than people expect, so firewalls must allow TCP port 53. The 16-bit query ID plus a randomised source port give about 32 bits an off-path attacker must guess to spoof an answer, the defence adopted after Kaminsky's 2008 attack. glibc's stub resolver waits 5 seconds before retrying a lost UDP query (resolv.conf(5)), so a single dropped packet shows up as a 5-second latency spike; in Kubernetes, a Linux conntrack race when A and AAAA queries leave the same socket in parallel produced exactly those spikes, which is one reason NodeLocal DNSCache skips DNAT and upgrades upstream queries to TCP (Kubernetes docs). The root's 13 server names are served by about 2,000 anycast instances (2,047 in October 2026, per root-servers.org), which is why a root outage has never taken down resolution.
Why it's built this way
- No single server can answer for every name, so authority is delegated down a tree.
- Walking the tree per lookup would be slow and melt its top, so answers, delegations and negatives are all cached.
- Caches cannot be told about changes, so TTL is the only consistency mechanism, and it is decided before the change.
- One small question and one small answer do not justify a connection, so DNS uses UDP, which caps message size (large answers fall back to TCP) and makes spoofing the main threat.
- Because so much rests on it, DNS favours availability over freshness: multiple nameservers, anycast, and serving stale data when authorities are unreachable.
Diagram
sequenceDiagram participant S as "Stub (app)" participant R as "Recursive resolver" participant Root as "Root server" participant T as "com server" participant A as "example.com server" S->>R: A www.example.com? Note over R: Cache miss, no delegation cached R->>Root: A www.example.com? Root-->>R: Referral: com NS + glue (TTL 2 days) R->>T: A www.example.com? T-->>R: Referral: example.com NS + glue (TTL 1 day) R->>A: A www.example.com? A-->>R: AA answer 192.0.2.1 (TTL 300) R-->>S: 192.0.2.1 Note over R: Next query for example.com names goes straight to A
Worked example
You are moving api.example.com from an old load balancer to a new one. The record has a 1-hour TTL, and about 50,000 distinct resolvers query it.
Two hours before the change you drop the TTL to 60 seconds. Authoritative load rises from 50,000 / 3,600 = 14 to 50,000 / 60 = 830 queries per second, a few dollars a day at managed-provider prices. At cutover most resolvers move within 2 minutes. The tail is resolvers that clamp TTLs, JVM services that cache addresses for the life of the process, and pooled connections that stay on the old load balancer, so you keep it serving for 24 hours and watch its traffic fall to zero.
Now the fleet side: 3,000 pods each make 400 external lookups per second with ndots:5 and no node-local cache. Each lookup becomes 8 queries, so cluster DNS sees 3,000 x 400 x 8 = 9.6 million queries per second, mostly NXDOMAIN for search-path guesses. Trailing dots plus a node-local cache cut that by two to three orders of magnitude.
In the wild
- AWS, 2025: automation empties a regional endpoint. On 19 and 20 October, a latent race between two DNS Enactors in DynamoDB's DNS management system let a delayed Enactor apply an old plan just before a cleanup job deleted that plan. The record for
dynamodb.us-east-1.amazonaws.comwas left with no IP addresses, and the system could not repair itself. DynamoDB API errors lasted from 23:48 to 02:40 PDT: DNS was fixed by hand at 02:25, and the last 15 minutes were cached answers expiring. AWS disabled the automation worldwide pending a fix (AWS). - Slack, 2021: a DNSSEC rollout that could not be rolled back fast. On 30 September, Slack signed
slack.comand published a DS record. A Route 53 bug returned NSEC answers for a wildcard without the right type bitmap, so validating resolvers cached "noAAAArecord" and then failedAlookups too. Pulling the DS record did not help, because resolvers had cached it for up to 24 hours (Google Public DNS capped it at 6), and some users could not reach Slack for about a day (Slack).
Trade-offs
| Option | Strengths | Weaknesses | Choose when |
|---|---|---|---|
| Long TTL (1 hour to 1 day) | Fewer queries, faster lookups, survives authority outages longer | Changes and failover are slow | Stable records, NS and delegations |
| Short TTL (30 to 60 s) | Fast changes and DNS failover | More queries and more cold lookups on the critical path | Records you may need to move during an incident |
| Single authoritative provider | Simple, one API, one set of features | Provider outage takes your names down | Small or internal zones |
| Two authoritative providers | Survives a provider outage | Must keep zones in sync; proprietary features (geo, ALIAS) do not mix | Revenue-critical public domains |
| GeoDNS steering | Cheap, works with any IP addresses | Steers resolvers, converges in minutes | Region selection |
| Anycast addresses | Routing reacts in seconds, no client cache | Needs BGP and owned address space | Edge networks and DNS servers themselves |
| Node-local caching resolver | Cuts latency and central resolver load | One more daemon per node to operate | Large Kubernetes or VM fleets |
Pitfalls in production
- Cached NXDOMAIN for a new name. Something queried the name before it existed and resolvers cached the negative answer, sometimes for an hour. Fix: a negative TTL of a few minutes, and create records before anything looks them up.
- Single DNS provider. The 2016 Dyn attack made many large sites unreachable although their servers were fine. Fix: a secondary provider for critical zones, kept in sync through zone transfers or infrastructure as code.
- Authoritative DNS that depends on your own network. In Facebook's 2021 outage the DNS servers withdrew their routes when backbone checks failed, so the names vanished, internal tools included (Meta). Fix: authoritative capacity and out-of-band access independent of your network.
- Search-path amplification.
ndots:5multiplies external lookups by four. Fix: fully qualified names with a trailing dot, a lowerndots, and node-local caching. - DNSSEC key rollover mistakes. A
DSrecord in the parent that no longer matches the zone's keys makes the zone fail validation everywhere at once. Fix: automate rollovers and monitor validation from an external validating resolver.
Leadership lens
- Treat DNS changes as production deploys: version-controlled zone files or Terraform, review, and a planned TTL schedule for migrations.
- Ask "what happens to us if our DNS provider is down for four hours?" and decide consciously between a second provider and accepting the risk.
- Make internal resolution an owned platform component with dashboards (query rate,
NXDOMAINshare, SERVFAIL rate, latency). - Expect DNS-based failover numbers in minutes and have them measured; promise faster failover only with anycast or client-side retry.
Check yourself
You lowered a record's TTL from 1 day to 60 seconds and changed its address in the same edit. Why do some clients still see the old address the next morning?
Show answer
Resolvers that cached the old answer under the 1-day TTL keep it until that TTL expires. The lower TTL only affects answers fetched after the edit, so it must be lowered at least one old TTL in advance.
Why does a warm recursive resolver almost never query a root server?
Show answer
It caches the delegations for TLDs such as
com, which carry two-day TTLs, and starts each new lookup from the closest cached ancestor zone.What is the difference between
NXDOMAINandSERVFAILfor caching and retries?Show answer
NXDOMAINis an authoritative "does not exist" that resolvers cache for the negative TTL.SERVFAILmeans the resolver failed to get an answer; it is cached only briefly and the client may retry or try another resolver.Why can a pod in Kubernetes send eight DNS queries to resolve
api.stripe.com?Show answer
With
ndots:5, a name with fewer than five dots is first tried with each search domain appended, and each attempt asks for bothAandAAAA.
Sources and further study
Primary
- RFC 7766: DNS Transport over TCP: why TCP support is mandatory, with connection reuse and pipelining.
- RFC 9156: DNS Query Name Minimisation: sending each ancestor zone only the labels it needs.
- RFC 9460: SVCB and HTTPS resource records: protocol hints, alternative endpoints and apex aliasing in DNS.
Systems docs
- Unbound configuration manual: prefetch, serve-expired and the infrastructure cache in a real recursive resolver.
- Kubernetes NodeLocal DNSCache: why a per-node cache avoids conntrack races and UDP timeouts.
- DNS Flag Day 2020: the 1,232-byte EDNS buffer and the TCP requirement for authoritative servers.
Books
- Computer Networking: A Top-Down Approach, Kurose and Ross, section 2.4 "DNS: The Internet's Directory Service": hierarchy, caching, records and message format.
- TCP/IP Illustrated, Volume 1 (2nd edition), Fall and Stevens, chapter 11 "Name Resolution and the Domain Name System": DNS on the wire, including EDNS and TCP fallback.
Other curricula
- donnemartin/system-design-primer: a short section on records, TTL caching and DNS-based routing (weighted, latency, geo), noting propagation delay and DDoS risk.
- Google SRE book, chapter 19: Load Balancing at the Frontend: DNS as the first tier of load balancing and why resolver caching limits it; it still cites the old 512-byte UDP limit, which EDNS lifted.
Watch
- How DNS Works (Computerphile): the delegation walk and caching explained on paper.
- Everything You Need to Know About DNS (ByteByteGo): record types, resolution and caching in one short overview.
Free resources
- RFC 1034: Domain Names, Concepts and Facilities: the original design, including the resolver algorithm in section 5.3.3.
- RFC 2308: Negative Caching of DNS Queries: how NXDOMAIN and NODATA are cached and for how long.
- RFC 8767: Serving Stale Data to Improve DNS Resiliency: the availability-over-freshness behaviour of modern resolvers.
- How updating DNS works (Julia Evans): why changes appear to "propagate", explained with real commands.
- Understanding how Facebook disappeared from the Internet (Cloudflare): what the 2021 outage looked like from a large resolver.
- Kubernetes DNS for Services and Pods: search domains,
ndotsand pod DNS policies.