System Design: Design a DNS System
Design a scalable Domain Name System. Covers recursive and authoritative resolution, zone file management, caching, anycast deployment, and handling billions of lookups daily.
What you'll learn
- ✓Understand recursive vs. authoritative DNS resolution
- ✓Design zone file storage and propagation
- ✓Implement multi-level caching with TTL management
- ✓Deploy DNS servers globally using anycast
- ✓Handle DNS-based load balancing and failover
Prerequisites
None — this post is self-contained.
The Domain Name System translates human-readable names like api.example.com into IP addresses. It is one of the oldest and most critical pieces of internet infrastructure, handling trillions of lookups daily. Despite its apparent simplicity, DNS involves hierarchical delegation, aggressive caching, eventual consistency, and global deployment — making it a rich system design topic.
Functional Requirements
- Resolve domain names to IP addresses (A, AAAA records).
- Support additional record types: CNAME, MX, TXT, SRV, NS.
- Allow domain owners to manage DNS records through an API and dashboard.
- Propagate record changes to all authoritative servers within minutes.
- Support DNS-based load balancing (returning different IPs based on geography or health).
Non-Functional Requirements
- Latency: resolve queries in under 10ms from the nearest server.
- Availability: DNS must be among the most available services on the internet. Target 100% uptime through redundancy.
- Throughput: each server must handle hundreds of thousands of queries per second.
- Consistency: after a record change, all servers must converge within 5 minutes.
DNS Resolution Flow
Understanding the resolution flow is essential before designing the system.
When a user types api.example.com into a browser:
- The browser checks its local DNS cache. If found and not expired, use it.
- The OS resolver checks its cache. If found, return it.
- The OS sends a query to the configured recursive resolver (typically provided by the ISP or a public resolver like 8.8.8.8).
- The recursive resolver checks its cache. If not found, it starts the resolution process.
- The recursive resolver queries a root name server: “Who handles
.com?” The root responds with the.comTLD servers. - The recursive resolver queries a
.comTLD server: “Who handlesexample.com?” The TLD responds with the authoritative name servers forexample.com. - The recursive resolver queries the authoritative name server for
example.com: “What is the A record forapi.example.com?” The authoritative server responds with the IP address. - The recursive resolver caches the result (respecting the TTL) and returns it to the client.
Our system needs to implement both the authoritative component (step 7) and optionally the recursive resolver component (steps 4-7).
Authoritative DNS Server Design
The authoritative server is the source of truth for a domain’s DNS records. When queried, it looks up the requested record and returns the answer.
Zone file storage. DNS records for a domain are organized into a zone. A zone contains all records for a domain and its subdomains (unless delegated to another zone). Store zones in a database:
dns_records
id UUID
zone_id UUID
name VARCHAR (e.g., "api.example.com")
type ENUM (A, AAAA, CNAME, MX, TXT, etc.)
value VARCHAR (e.g., "203.0.113.42")
ttl INT (seconds)
priority INT (for MX records)
updated_at TIMESTAMP
Index on (name, type) for fast lookups.
Query processing. When a query arrives for api.example.com type A:
- Look up the zone for
example.com. - Search for a record matching the name and type.
- If a CNAME is found instead of an A record, follow the CNAME chain.
- Return the answer with the appropriate TTL.
For performance, load the entire zone into memory at startup and serve queries from RAM. Zone data is typically small (megabytes, even for large domains). Watch for database changes and reload the zone when records are updated.
Recursive Resolver Design
The recursive resolver does the heavy lifting of walking the DNS hierarchy on behalf of clients.
Caching is everything. A recursive resolver without caching would be painfully slow and would overwhelm upstream servers. Cache every response, keyed by (name, type), with a TTL from the response’s TTL field.
Cache structure:
- Positive cache: stores successful responses. Entries expire after the record’s TTL.
- Negative cache: stores NXDOMAIN (name does not exist) responses. These are cached with the SOA record’s minimum TTL, preventing repeated lookups for non-existent names.
Iterative resolution. The resolver maintains a queue of pending queries. For each query not in cache, it iteratively queries root, TLD, and authoritative servers. It caches intermediate results (NS records for TLDs, for example) to skip steps on future queries.
Concurrency. Multiple clients may request the same name simultaneously. Use request coalescing: if a resolution for api.example.com is already in progress, queue additional requests and serve them all from the same resolution result. This prevents query amplification under load.
Zone Propagation
When a domain owner updates a record through the management API, the change must propagate to all authoritative servers.
Primary-secondary replication. Designate one server as the primary and others as secondaries. When a record changes on the primary, it increments the zone’s serial number in the SOA record. Secondaries periodically check the serial number (zone transfer poll) and initiate a zone transfer (AXFR for full, IXFR for incremental) if the serial has increased.
NOTIFY mechanism. Rather than waiting for secondaries to poll, the primary sends a DNS NOTIFY message to all secondaries immediately after a change. The secondaries then initiate a zone transfer. This reduces propagation delay from minutes to seconds.
Modern approach: database-backed. Instead of file-based zone transfers, have all authoritative servers read from the same replicated database (PostgreSQL with read replicas, or a distributed store like CockroachDB). Changes are visible to all servers as soon as the database replicates. This eliminates the primary-secondary distinction and simplifies operations.
Global Deployment with Anycast
Deploy authoritative servers across multiple geographic locations and advertise the same IP address from all locations via anycast BGP. When a recursive resolver queries the authoritative IP, the query is routed to the nearest deployment by the internet’s routing infrastructure.
Benefits:
- Low latency: queries reach the geographically closest server.
- DDoS absorption: attack traffic is distributed across all locations rather than concentrating on one.
- Automatic failover: if a location goes down, BGP withdraws the route, and traffic shifts to the next nearest location.
Deploy at least three anycast locations across different continents for a production DNS service.
DNS-Based Load Balancing
DNS can distribute traffic across multiple backends:
Round-robin. Return multiple A records for the same name. Clients typically use the first one, and DNS servers rotate the order on each response. This provides basic load distribution but no health awareness.
Geographic routing. Return different IP addresses based on the resolver’s location (determined by the resolver’s IP or EDNS Client Subnet). Route European users to European servers and North American users to North American servers.
Health-checked routing. Monitor the health of each backend IP. Remove unhealthy IPs from the DNS response. This provides automatic failover but is limited by DNS caching — clients may hold stale records for up to the TTL.
Weighted routing. Assign weights to IPs and probabilistically include them in responses. Use this for gradual traffic shifts during migrations.
Security: DNSSEC
DNS was designed without authentication, making it vulnerable to spoofing (an attacker returning fake IP addresses). DNSSEC adds cryptographic signatures to DNS records.
Each zone signs its records with a private key. The corresponding public key is published as a DNSKEY record and authenticated by the parent zone (the .com zone signs a DS record pointing to example.com’s key). Recursive resolvers validate the chain of signatures from the root to the queried zone.
DNSSEC adds complexity (key rotation, larger responses, signature computation) but is essential for security-critical domains.
Monitoring
- Query rate: queries per second, broken down by record type and response code.
- Resolution latency: time to resolve queries, both cached and uncached.
- Cache hit ratio: for recursive resolvers, this is the primary performance indicator. Target above 90%.
- Zone propagation delay: time between a record change and its availability on all authoritative servers.
- SERVFAIL rate: the percentage of queries that fail. This should be near zero.
Scaling Considerations
- Recursive resolver scaling: deploy multiple resolver instances behind a load balancer. Each instance maintains its own cache, so more instances means more aggregate cache capacity but lower per-instance hit ratios. Use consistent hashing on the query name to route queries to the same resolver for better cache efficiency.
- Authoritative server scaling: since zones are read-only (writes go through the management API), scaling reads is straightforward. Add more anycast locations or more servers per location.
- Large zones: for domains with millions of records (CDN providers), partition the zone across multiple server groups by name prefix.
Summary
A DNS system combines authoritative servers (the source of truth for domain records) with recursive resolvers (the caching intermediaries that walk the hierarchy). The critical design decisions are how you propagate zone changes (NOTIFY plus incremental transfers or database replication), how you deploy globally (anycast), and how aggressively you cache (positive and negative caching with request coalescing). DNS’s simplicity is deceptive — its global scale, caching semantics, and security requirements make it one of the most interesting distributed systems to design.
Related articles
- System Design System Design: Design a Content Delivery Network
Design a CDN that serves static and dynamic content from edge locations worldwide. Covers caching tiers, cache invalidation, origin shielding, and anycast routing.
- System Design System Design: Design a Collaborative Document Editor
Design a real-time collaborative editor like Google Docs. Covers conflict resolution with CRDTs and OT, presence awareness, cursor synchronization, and offline editing support.
- System Design System Design: Design an Object Storage System
Design an object storage system like Amazon S3. Covers metadata management, data placement, erasure coding, consistency models, and multi-tenant isolation at petabyte scale.
- AWS AWS Route 53 Routing Policies Explained
Understand simple, weighted, latency, failover, geolocation, and multivalue routing policies in Amazon Route 53 with real examples.