System Design

Design DNS

Step 1 / 9

Learn system design by building the Domain Name System step by step.

The numbers to beatroot→ TLDTLD→ authoritativeauth→ the record

In the interview room

How you’d open this design in an interview

Before any boxes: agree what it must do, pin the qualities that shape everything, then build — naming each trade-off as you make it. The walkthrough above is that exact order.

Functional requirements

What it must do — agree on these before drawing a single box.

  • Resolve a name: given vibeengines.com, return its IP address.
  • Delegate ownership: a hierarchy — root → TLD → authoritative — where each zone is independently owned.
  • Walk it for the client: a recursive resolver follows referrals so the stub client asks just once.
  • Cache with TTL: reuse answers for their owner-set TTL so most lookups skip the hierarchy.
  • Steer traffic: GeoDNS returns different IPs by location, health or weight — DNS as a coarse load balancer.

Non-functional requirements

The qualities that shape the whole design — each one names the mechanism that buys it.

No single owner or central bottleneck
Split the namespace into a delegated tree (root→TLD→authoritative); each level owns and points one step down, so no server holds everything.
Keep clients dumb
A recursive resolver does the whole root→TLD→authoritative walk and returns just the answer; the OS stub resolver asks it one question.
Feel instant, and shield the hierarchy
Resolvers cache each answer for its owner-set TTL, so the vast majority of lookups never touch root/TLD/authoritative at all.
Never go dark, survive DDoS
Replicate every level and front each address with anycast — one IP served from the nearest healthy machine, a dead node just routed around.
Send users to the nearest/healthy region
GeoDNS on the authoritative side returns different IPs by location, health or weight — a coarse global load balancer and failover.
Trustworthy answers on a hostile internet
DNSSEC signs records so resolvers detect forged answers; negative caching and low pre-change TTLs handle NXDOMAIN and propagation.

The trade-offs you say out loud

Senior signal isn’t the boxes — it’s naming what you gave up and why it was the right price.

Split & delegate the namespaceover one central name→IP table

A single global table fails three ways at once — load (no machine serves the planet’s queries), availability (one thing to DDoS down), control (no entity should own every name). Hierarchy + delegation solves all three.

A recursive resolverover every device walking the tree itself

Making every stub device chase the hierarchy is wasteful and un-cacheable across users. One shared resolver walks the tree once and caches the answer for everyone behind it.

A delegated treeover a central directory of which server holds what

A directory of locations is just the central table one indirection removed. The name’s own dotted structure tells you where to go next, so the hierarchy needs no global index.

Cache answers for their TTLover walking the full hierarchy every lookup

A three-server walk per lookup would be slow and crush the root and TLDs. Caching for the owner-set TTL serves ~90%+ from the resolver — the same freshness-vs-load dial a CDN uses.

Replication + anycastover one hardened server per level

One box, however powerful, is still one target and one failure. Anycast (one IP announced from many places) turns each root/TLD/zone into a self-healing swarm — an attack hits one node and traffic flows to the rest.

What this teaches

Learn system design by building the Domain Name System step by step. An interactive guide covering why one central name→IP table can't work, a delegated hierarchy of root / TLD / authoritative servers, recursive resolution, caching with TTL, replication and anycast for availability, GeoDNS and latency-based routing, and the unhappy paths (propagation, negative caching, DDoS, DNSSEC).

Key takeaways

  • One central name→IP table fails on load, availability and control — so split and delegate it.
  • A recursive resolver does the multi-step walk so clients stay dumb (a stub resolver).
  • A delegated hierarchy: root → TLD → authoritative, each owning and pointing down one level.
  • Resolution follows referrals from the root hints down to an authoritative A record.
  • Caching with owner-set TTLs serves most lookups instantly and shields the hierarchy.
  • Replication + anycast make the root, TLDs and zones self-healing and DDoS-resistant.
  • GeoDNS steers users to nearby/healthy servers; DNSSEC, negative caching and low TTLs handle the edges.

Concepts covered

  • What does DNS do?
  • One giant lookup table?
  • The recursive resolver
  • A delegated hierarchy
  • Recursive resolution, step by step
  • Caching with TTL
  • Replication & anycast
  • GeoDNS & traffic steering
  • Propagation, negatives, security
▶  Watch it explained

Prefer a video walkthrough?

Design DNS — read the full walkthrough as text

the same steps, decisions & trade-offs, for reading, reference & search

The big idea

What does DNS do?

Computers talk over IP addresses (142.250.72.14); humans remember names (google.com). Something has to translate names to addresses — billions of times a second, for every domain on Earth, with no central owner and no downtime. That's a deceptively hard distributed-systems problem.

DNS is the internet's phone book: give it a name, it returns an address. The trick is doing it at planetary scale. There's no single table — the namespace is split into a hierarchy that's delegated to independent owners, walked by resolvers, and made fast by aggressive caching.

How to read this: Each step opens with a real design decision — make the call before I show you what ships. Watch the tree grow, and at the end drop the cache and kill a nameserver to see why DNS almost never goes down. Hit Begin.

Step 1 · The naive table

One giant lookup table?

The simplest design: one central server holding a table of every name → IP mapping on the internet. Every device queries it. Why is that a non-starter?

Design decision: One central name→IP table for the whole internet. What breaks first?

The call: It can't take the load, it's a single point of failure, and no one entity can own all names. — One table means one bottleneck, one thing to DDoS into oblivion, and one owner deciding every domain on Earth. DNS solves all three by splitting and delegating the namespace.

Three fatal problems: load (no machine serves the whole internet's queries), availability (one table is one thing to kill), and control (no single entity should own every name). The answer to all three is the same: don't centralize the table — split and delegate it.

Why not centralize: Any design where the whole world depends on one component fails on scale, resilience and politics at once. DNS is a case study in solving all three with hierarchy + delegation + caching rather than a bigger box.

Step 2 · Someone to do the walking

The recursive resolver

If the answer isn't in one place, a client would have to chase it across many servers. You don't want every phone and laptop implementing that whole dance. Who does the legwork?

Design decision: If no single server has the answer, who does the multi-step lookup for the client?

The call: A recursive resolver: the client asks it once, it walks the hierarchy and returns the final answer. — The OS stub resolver hands the whole question to a recursive resolver (your ISP's, or 8.8.8.8). It does the root→TLD→authoritative walk and returns just the answer — and caches it to help the next user.

Introduce the recursive resolver (your ISP's, or a public one like 8.8.8.8). The client's tiny stub resolver asks it one question — "what's the IP for vibeengines.com?" — and the resolver does all the walking, returning just the final answer. It also caches, so it can answer the next person instantly.

Stub vs recursive: The stub resolver in your OS is dumb on purpose — it just forwards to a recursive resolver. The recursive resolver is the workhorse that walks the tree and caches results for all its users. Splitting "ask" from "resolve" is what keeps clients simple.

Step 3 · Split the namespace

A delegated hierarchy

The resolver needs to find the answer without any one server knowing everything. How do you organize billions of names so the lookup is a short, delegated walk instead of one impossible table?

Design decision: How is the name space organized so no server holds everything?

The call: A tree: root delegates to TLDs (.com), which delegate to the domain's authoritative server. — Read a name right-to-left: root knows who runs .com; the .com TLD knows who runs vibeengines.com; that authoritative nameserver holds the actual records. Each level owns and delegates its slice.

Organize names as a tree, read right-to-left, with each level delegating to the next. The root knows which servers run each TLD; the TLD servers (.com) know which authoritative nameserver owns vibeengines.com; that authoritative server holds the real records. No server knows everything — each just points one step down.

Delegation: www.vibeengines.com. → the trailing dot is the root. Root → ".com is over there." .com → "vibeengines.com's nameserver is over there." Authoritative → "here's the IP." Three delegations, and every zone is independently owned and operated.

Step 4 · The walk

Recursive resolution, step by step

Put it together: the resolver has a name and knows the tree exists. Trace exactly how it turns vibeengines.com into an IP starting from knowing nothing but the root.

The resolver walks down: ask a root server → it refers you to the .com TLD servers. Ask a TLD server → it refers you to vibeengines.com's authoritative nameserver. Ask the authoritative server → it returns the A record (the IP). Three referrals, one answer. The resolver hands it back to the client — and remembers it.

Referrals, not redirects: Each server the resolver asks either answers (authoritative) or refers ("I don't know, but ask these servers one level down"). The resolver follows referrals until it hits an authoritative answer. It always knows where to start because every resolver ships with the root hints — the addresses of the root servers.

Step 5 · Why it feels instant

Caching with TTL

A three-server walk for every single lookup would be slow, and would crush the root and TLD servers under the whole internet's traffic. Yet DNS feels instant. What makes it fast and spares the upstream servers?

Design decision: A full walk every lookup would be slow and crush the root/TLDs. What saves it?

The call: Resolvers cache answers for a TTL; most lookups never leave the resolver. — Each record carries a TTL set by its owner. The resolver caches the answer for that long, so the overwhelming majority of queries are served from cache and never touch root/TLD/authoritative servers at all.

Caching with a TTL. Every record carries a Time To Live set by its owner (e.g. 300s or a day). The resolver caches each answer for that long, so almost every lookup is served straight from the resolver's memory — never touching the hierarchy. Caching is what makes DNS fast and what keeps the root and TLD servers from being overwhelmed.

TTL is the trade dial: A long TTL means fewer upstream queries and faster answers, but changes take longer to spread. A short TTL means quick updates but more load and slower average lookups. The record owner picks the TTL to trade freshness against load — the same lever a CDN uses.

Step 6 · Never go dark

Replication & anycast

The root, the TLDs and each zone's authoritative server are now critical infrastructure. A single machine for any of them would be a global outage waiting to happen — and an irresistible DDoS target. How do you make them unkillable?

Design decision: The root/TLD/authoritative servers are critical. How do you make them survive failure and attack?

The call: Replicate every level and serve each address from many machines via anycast. — Every zone runs multiple authoritative servers; the 13 root "identities" are each anycast to hundreds of physical servers worldwide. Many machines share one address, so load spreads and a dead one is simply routed around.

Replicate everything and front it with anycast. Every zone must run multiple authoritative nameservers. The 13 root server identities are each anycast to hundreds of physical machines around the globe — one IP, served from the nearest healthy instance. Load spreads, latency drops, and a dead server (or a DDoS on one location) is just routed around.

Anycast for infrastructure: Anycast (one IP announced from many places, network delivers to the nearest) turns a would-be single point of failure into a self-healing swarm. It's why the root — a constant DDoS target — has never been globally downed: an attack hits one anycast instance, and traffic flows to the others.

Step 7 · Smarter answers

GeoDNS & traffic steering

DNS can do more than return a fixed IP. The same name can resolve to different addresses for different users — to send them to a nearby data center, balance load, or route around an unhealthy region. How?

On the authoritative side, add GeoDNS / traffic management: return a different IP based on the resolver's location (nearest data center), server health (skip a down region), or weight (split traffic for a canary). This makes DNS a coarse global load balancer and failover mechanism — the first hop of routing users to the right place (exactly what a CDN leans on).

DNS as a routing layer: Because the authoritative server chooses what to answer, it can steer: latency-based (nearest), geo (by country), weighted (A/B), or failover (health-checked). The catch is TTL — steering only re-routes as fast as caches expire, so failover TTLs are kept short.

Step 8 · The sharp edges

Propagation, negatives, security

Real DNS has famous gotchas: changes that "haven't propagated," repeated lookups of names that don't exist, DDoS amplification, and the fact that a plain DNS answer can be forged.

Propagation delay is just caching: a change is invisible until old TTLs expire, so you lower TTLs before a planned change. Negative caching remembers NXDOMAIN (name doesn't exist) so typos don't hammer the hierarchy. Defend against DDoS/amplification with anycast capacity and rate limiting. And DNSSEC cryptographically signs records so resolvers can detect forged answers (cache poisoning).

Design for the unhappy path: Record changed → wait out the TTL (lower it first). Name doesn't exist → negative-cache the NXDOMAIN. Under attack → anycast + rate limit. Answer forged → DNSSEC signatures. The elegant core (hierarchy + cache) needs these guards to survive the real, hostile internet.

You did it

You just designed DNS.

  • One central name→IP table fails on load, availability and control — so split and delegate it.
  • A recursive resolver does the multi-step walk so clients stay dumb (a stub resolver).
  • A delegated hierarchy: root → TLD → authoritative, each owning and pointing down one level.
  • Resolution follows referrals from the root hints down to an authoritative A record.
  • Caching with owner-set TTLs serves most lookups instantly and shields the hierarchy.
  • Replication + anycast make the root, TLDs and zones self-healing and DDoS-resistant.
  • GeoDNS steers users to nearby/healthy servers; DNSSEC, negative caching and low TTLs handle the edges.
built to name the whole internet without a single owner — make the calls, drop the cache, run the gauntlet.
Finished this one? 0 / 65 System Designs done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More System Designs