system-design

DNS: The Internet’s Phone Book

The largest distributed database in the world, your first load balancer, your slowest failover mechanism, and a shockingly common cause of total outages.

Prerequisites: Networking 101 Time to read: ~16 minutes


The problem

Servers are found by IP address: 93.184.216.34. Humans cannot remember those, and more importantly, IPs change — you replace a server, add a region, fail over to a backup. If every client hard-coded an IP, every change would break every client.

So you need a layer of indirection: a name that maps to an address, where the mapping can change without anyone updating their code.

That’s DNS. And because it’s indirection, it also becomes the place where you do global load balancing, geographic routing, and failover.


🧠 Mental model: asking for directions

You want “Café Aroma” and only know the name.

  1. You check your own memory. (Browser/OS cache — instant.)
  2. You ask the hotel concierge, whose job is to find out for you. (Recursive resolver — your ISP, 8.8.8.8, or 1.1.1.1.)
  3. The concierge doesn’t know either, so they ask the city information desk: “who handles cafés?” (Root server → “ask the .com desk.”)
  4. The .com desk says “Café Aroma’s own office handles their locations, here’s their number.” (TLD server → authoritative nameservers.)
  5. The café’s own office gives the address. (Authoritative nameserver — the source of truth.)
  6. The concierge remembers this for a while so the next guest gets an instant answer. (Caching, for the TTL.)

The hierarchy is what makes DNS scale: no single machine knows everything, and each level only knows who to delegate to.


How resolution actually works

sequenceDiagram
    participant App
    participant OS as OS cache
    participant R as Recursive resolver<br/>(8.8.8.8)
    participant Root as Root (.)
    participant TLD as .com TLD
    participant Auth as ns1.example.com

    App->>OS: api.example.com?
    Note over OS: miss
    OS->>R: api.example.com?
    R->>Root: api.example.com?
    Root-->>R: ask the .com servers
    R->>TLD: api.example.com?
    TLD-->>R: ask ns1.example.com
    R->>Auth: api.example.com?
    Auth-->>R: 93.184.216.34, TTL 300
    R-->>OS: 93.184.216.34
    Note over R: cached for 300 s

📐 Cost: a fully cold lookup is 20–120 ms (four sequential round trips). A cached one is ~0 ms. In practice the vast majority of lookups are cached somewhere in that chain, which is the only reason the root servers survive.

The caching layers, in order: browser cache → OS resolver cache → recursive resolver cache → (finally) authoritative. Each holds the answer for the record’s TTL.


Record types you must know

Type Maps Example Notes
A name → IPv4 example.com → 93.184.216.34 The basic one
AAAA name → IPv6 example.com → 2606:2800:220:1:: “quad-A”
CNAME name → another name www.example.com → example.com Cannot coexist with other records at the same name; cannot be used at the zone apex (example.com itself)
ALIAS / ANAME apex → another name example.com → lb.aws.com Provider-specific fix for the CNAME-at-apex limitation
MX mail servers example.com → mail.example.com (pri 10) Priority-ordered
TXT arbitrary text SPF, DKIM, domain verification How every SaaS proves you own the domain
NS delegation example.com → ns1.provider.com Who is authoritative
SRV service + port _sip._tcp.example.com → 5060 sip.example.com Used by service discovery, SIP, Kubernetes
PTR IP → name reverse lookup Mail servers check this for spam scoring
CAA which CAs may issue certs   Prevents rogue certificate issuance

🚨 The CNAME-at-apex limitation trips up almost everyone once. You cannot CNAME example.com to a load balancer hostname, because the apex must also hold NS and SOA records. Use your provider’s ALIAS/ANAME record, or an A record pointing at a static IP.


TTL: the single most important design knob

The TTL says how long resolvers may cache an answer.

TTL Good Bad
60 s Failover in ~1 minute; agile ~50× more query volume; more cold lookups (slower for users)
3600 s (1 h) Balanced default Failover takes up to an hour
86400 s (24 h) Cheapest, fastest for users A mistake takes a full day to undo

⚖️ The trade-off: TTL is the dial between agility and efficiency. Low TTL = fast changes, higher cost and latency. High TTL = fast lookups, slow changes.

The standard playbook before a planned migration: drop the TTL to 60 s at least 24–48 hours beforehand (so the old, long TTL has expired everywhere), do the migration, then raise it back. Doing this on the day of the migration is useless — resolvers are still holding the old long-TTL answer.

🚨 And here’s the part that matters most in interviews: even with a 60-second TTL, DNS failover is not reliable failover. Many resolvers ignore short TTLs. Java’s JVM historically cached DNS forever by default. Browsers pin connections. Some corporate resolvers enforce their own minimums. If your recovery plan depends on DNS propagating in 60 seconds, your recovery plan does not work. Use load balancers, anycast, or client-side retries for fast failover, and treat DNS as your slow, coarse-grained control.


DNS as a load balancing and routing tool

Because DNS is a mapping under your control, you can return different answers to different people.

Round-robin DNS. Return multiple A records; clients pick one (usually the first, or randomly).

GeoDNS. Return the IP of the nearest region based on the resolver’s location. Karachi → Dubai region; Frankfurt → EU region. This is the standard way to do multi-region routing. Caveat: you see the resolver’s location, not the user’s — someone using 8.8.8.8 may appear to be somewhere else (mitigated by the EDNS Client Subnet extension).

Latency-based routing. The provider measures real-world latency and returns whichever region is actually fastest, which isn’t always the geographically nearest.

Weighted routing. 95% of answers point to v1, 5% to v2. A blunt but effective canary mechanism. → Deployment Strategies

Health-checked failover. The DNS provider probes your endpoints and stops returning unhealthy ones. Better than plain round-robin, still bounded by TTL and resolver behaviour.

Anycast — the technique that actually delivers fast global routing. The same IP address is announced from many datacenters worldwide, and BGP routes each user to the nearest one. No DNS change is involved, so failover is at network speed (seconds), not TTL speed. This is how 1.1.1.1, 8.8.8.8, and every serious CDN work.


When DNS breaks, everything breaks

DNS is a genuine single point of failure and has a long history of proving it. Some patterns worth knowing:

Mitigations to mention in interviews:


DNS inside your own systems

DNS isn’t just public. It’s the backbone of internal service discovery:

Practical consequence: never hard-code IPs in configuration. Use names, so instances can be replaced without a deploy. Also, be aware of client-side DNS caching in your language runtime — the JVM’s networkaddress.cache.ttl default has caused a memorable number of “we failed over but the app kept hitting the dead host” incidents.


Security notes


🚨 Interview traps


🎙️ Soundbites


🛠️ Try it

dig example.com                     # basic lookup — note the TTL in the answer
dig +trace example.com              # walk the hierarchy yourself: root → TLD → authoritative
dig example.com NS                  # who's authoritative?
dig example.com MX                  # mail routing
dig -x 8.8.8.8                      # reverse lookup
dig @1.1.1.1 example.com            # ask a specific resolver
dig google.com                      # run twice, watch the TTL count down in the cached answer

Then look up a large site (dig +short netflix.com) and notice how many addresses come back, and whether the answers change when you query from a different resolver. That’s GeoDNS in action.


Check yourself

1. Why can't you use a CNAME at the zone apex (example.com)? A CNAME means "this name is an alias — ignore everything else here." But the apex must hold NS and SOA records to exist as a zone at all, and those can't coexist with a CNAME. Providers work around it with non-standard ALIAS/ANAME records that resolve the target server-side and return an A record.
2. You set a 60-second TTL and failed over. Some users still hit the dead server 20 minutes later. Why? Resolvers and clients don't all honour TTLs. Some ISP resolvers enforce a minimum. Some runtimes (historically the JVM) cache DNS indefinitely. Browsers pin existing connections. Corporate proxies cache aggressively. This is exactly why DNS is a coarse control and not a failover mechanism — fast failover belongs at the load balancer or anycast layer.
3. What's the difference between GeoDNS and anycast for routing users to the nearest region? GeoDNS returns a *different IP* per user based on their (resolver's) location — it's a DNS-layer decision, subject to caching and resolver-location inaccuracy. Anycast announces the *same IP* from many locations and lets BGP routing pick the nearest — it's a network-layer decision, unaffected by DNS caching, and reroutes in seconds when a location goes offline. Anycast is more powerful; GeoDNS is easier to run on your own.
4. What is a subdomain takeover and how does it happen? You point `blog.example.com` at a hosting provider via CNAME, later delete the hosted resource, but forget the DNS record. An attacker registers that same resource name at the provider, and now their content is served from your domain — with your cookies, your CSP allowances, and your users' trust. Prevention: audit for dangling CNAMEs, and remove DNS records as part of decommissioning.
5. Your site is completely unreachable but all your servers are healthy and serving traffic fine when hit by IP. Where do you look? DNS. Either your authoritative nameservers are unreachable (DDoS, provider outage, or withdrawn BGP routes), your records were changed/deleted, the domain expired, or DNSSEC validation is failing. Test with `dig @ example.com` to bypass caches and isolate whether the authoritative layer is answering. </details> --- ## Further reading - [HTTP, HTTPS, and TLS](/system-design/01-foundations/05-http-https-tls.html) — next - [CDN](/system-design/02-building-blocks/04-cdn.html) — anycast in practice - [Multi-Region & DR](/system-design/09-deployment-and-infra/08-multi-region-and-dr.html) - Cloudflare's [DNS learning centre](https://www.cloudflare.com/learning/dns/what-is-dns/)