Art of Codeartofcode
LLeeaarrnniinngg
BBlloogg
TToooollss
GGaammeess AArreennaa
JJoobbss
LLiivvee CCoouurrsseess

Courses

  • System DesignHigh-level system design, one everyday scene at a time: 30 concepts and 15 interview rounds.712 lessons
All coursesTutorialsMy Learning

Categories

  • 01AI & Tools
  • 02Tutorials
  • 03Engineering
  • 04Reviews
  • 05Build Logs
  • 06Tales of Misfits
  • 07Opinion
  • 08Career
  • 09News

Read & write

All storiesEvery post, newest first.Write for usPublish your stories and earn from what you write.Writer leaderboardsWho is writing the most read posts.

Categories

  • PDF Tools25
  • Development09
  • Utilities10
  • Design04
  • Converters04
  • Generators02

Featured

JSON FormatterFormat, validate and minify JSON.Regex TesterTest patterns against live text.Merge PDFCombine PDFs in your browser.JWT DecoderRead a token’s header and claims.Password GeneratorStrong passwords, generated locally.Gradient GeneratorBuild CSS gradients visually.
All 53 tools

Play a round

DevdleOne developer word a day, six guesses.Python RushClassic snake, with coding icons to eat.Blink or BreakA quick test of your reflexes.
Games Arena

Learn with us

Live CoursesInstructor-led courses. Join a waitlist and be first in when one starts.LearningStructured programming courses with AI assistance and certificates.

System Design

4. DNS

Lesson 13 of 15

4. DNS

1
The picture to keep in your head
2
4.1 Why do we need names at all?
3
4.2 What are the parts of a domain name?
4
4.3 What happens, step by step, when a name is looked up?
5
4.4 What kinds of DNS records are there?
6
4.5 What is a TTL, and why does DNS cache so much?
7
4.6 How can DNS spread users across servers or send them to the nearest one?
8
4.7 Why do DNS changes "take time to propagate"?
9
4.8 What happens when DNS fails?
10
Memory card and where the analogy breaks
11
Practice: five levels
12
Interview questions
13
Solutions
14
Sources
15
Code lab
4. DNS

Solutions

3 min read+10 XP

Solutions

Level 1

reveal

Level 2

reveal

Level 3

reveal

Level 4

reveal

Level 5 (sketch)

reveal

No tracks available

Lofi Player

artofcode

artofcode.in

The den of devs.

Stories, tools, games, and gear for developers.

Read the StoriesEExxpplloorree TToooollss
Art of Codeartofcode

Platform

  • BBlloogg
  • TToooollss
  • GGaammeess AArreennaa
  • CCoouurrsseess
  • LLeeaarrnniinngg
  • CCaammppuuss

Company

  • AAbboouutt UUss
  • JJoobbss && IInntteerrnnsshhiippss
  • CCoonnttaacctt

Legal

  • TTeerrmmss ooff SSeerrvviiccee
  • PPrriivvaaccyy PPoolliiccyy
  • RReeffuunndd PPoolliiccyy

Copyright © 2026 artofcode.in, All Rights Reserved.

IST·--:--

1Show the Level 1 solution
2**A.**
31. **A** record: `api.example.com → 203.0.113.30`.
42. **CNAME**: `blog.example.com → hosting.blogplatform.net`.
53. Two **MX** records, e.g. priority 10 (main) and 20 (backup). Lower number is preferred.
64. A **TXT** record with the value the console gives you.
75. An **AAAA** record.
8
9**B.**
101. **False.** Nothing is pushed. Resolvers keep the old answer until its TTL expires, so it can take up to the old TTL.
112. **False.** DNS doesn't know a server is dead. Cached answers keep including the dead IP until the TTL runs out, unless a health-checked DNS service removes it (and even then, after the TTL).
123. **False** in standard DNS. The bare domain must hold NS and SOA records, and a CNAME can't share its name with other records. Use your provider's ALIAS or "CNAME flattening" feature, or A records.
Show the Level 2 solution
1. About one query per resolver per TTL: 10,000 ÷ 300 ≈ **33 queries a second**.
2. 60 seconds: 10,000 ÷ 60 ≈ **167 a second**. 1 day: 10,000 ÷ 86,400 ≈ **0.12 a second** (about one every 9 seconds).
3. Empty cache: 10 (user to resolver) + 3 × 30 (root, TLD, authoritative) = **100 ms**. Cached at the resolver: **10 ms**. (Cached in the browser or OS: almost 0.)
4. Up to **24 hours**, the old TTL. Some misbehaving caches may hold it even longer.
1Show the Level 3 solution
2Tested solution (Python 3):
3
4```python
5ROOT = {"com.": "tld-com"}
6SERVERS = {
7    "tld-com": {"example.com.": "ns1.example.com"},
8    "ns1.example.com": {
9        ("A", "example.com."): ("203.0.113.10", 300),
10        ("CNAME", "www.example.com."): ("example.com.", 300),
11        ("A", "shop.example.com."): ("203.0.113.20", 300),
12    },
13}
14
15
16class Resolver:
17    def __init__(self, servers=SERVERS, root=ROOT, negative_ttl=60):
18        self.servers, self.root = servers, root
19        self.cache = {}          # name -> (ip or None, expires_at)
20        self.queries = 0
21        self.negative_ttl = negative_ttl
22
23    def _ask(self, server, question):
24        self.queries += 1
25        return self.servers[server].get(question)
26
27    def resolve(self, name, now=0, depth=0):
28        if depth > 8:
29            raise RuntimeError("CNAME loop")
30        hit = self.cache.get(name)
31        if hit and hit[1] > now:
32            return hit[0]                                  # answered from cache
33
34        tld = name.rstrip(".").split(".")[-1] + "."
35        self.queries += 1                                  # ask the root
36        tld_server = self.root.get(tld)
37        zone = ".".join(name.rstrip(".").split(".")[-2:]) + "."
38        auth = self._ask(tld_server, zone) if tld_server else None
39        if auth is None:
40            self.cache[name] = (None, now + self.negative_ttl)  # NXDOMAIN, cached briefly
41            return None
42
43        a = self._ask(auth, ("A", name))
44        if a:
45            ip, ttl = a
46            self.cache[name] = (ip, now + ttl)
47            return ip
48        cname = self._ask(auth, ("CNAME", name))
49        if cname:
50            target, ttl = cname
51            ip = self.resolve(target, now, depth + 1)
52            if ip:
53                self.cache[name] = (ip, now + ttl)
54            return ip
55        self.cache[name] = (None, now + self.negative_ttl)
56        return None
57```
58
59All five checks pass. The full file, including the checks and the Level 4 simulation, is in `code/ch04_dns.py`.
60
61*Simplification:* a real resolver also caches the referrals (root and `.com` answers), so most lookups skip straight to the authoritative server. Adding that is a good extension.
1Show the Level 4 solution
2**The bug:** the record had a **1-day TTL**, and the old servers were switched off **immediately** after changing it.
3
41. Many resolvers cached `shop.example.com → 203.0.113.20` some time in the day before the move, valid for up to 24 hours.
52. The record is changed. Nothing is pushed: those resolvers keep their cached answer.
63. The old servers are switched off right away.
74. Users behind those resolvers are sent to `203.0.113.20`, which no longer answers. **For them the site is down**, for up to a day, while the new servers sit healthy and idle.
8
9The tested simulation shows a user asking one hour after the move still gets the old IP; with the TTL lowered two days early, the same user gets the new one.
10
11**The fixed runbook:**
12```
131. At least 2 days before: lower the TTL of shop.example.com to 300 seconds.
142. Start the new servers at 198.51.100.7 and test them directly.
153. Change the A record to 198.51.100.7.
164. Keep the old servers running (or forwarding to the new ones) for at least
17   the old TTL plus a margin; watch their traffic fall to near zero.
185. Switch off the old servers.
196. Raise the TTL back to its normal value.
20```
1Show the Level 5 (sketch) solution
21. **Routing:** a managed DNS service with **geographic or latency-based routing**: users near India get the Mumbai load balancers' address, Europe gets Frankfurt, the Americas get Virginia. Load balancers inside each region spread traffic across servers (Chapter 7).
32. **Region down:** DNS **health checks** notice Frankfurt is unhealthy and stop returning it; European users get the next-nearest healthy region. With a **60 to 300 second TTL**, most move within minutes. Each region needs spare capacity to absorb another region's users (Chapter 29).
43. **TTLs:** 60 to 300 seconds for the main traffic records (fast failover); hours for MX, TXT and other stable records (less load, more resilience).
54. **DNS provider outage:** serve the zone from **two independent DNS providers** (both listed as NS records), keep moderate TTLs so cached answers survive short outages, and monitor resolution from several regions.
65. **Limit:** routing uses the **resolver's** location and changes are delayed by caching. Work around it with **anycast** addresses or a CDN in front (Chapter 26), short TTLs on routed records, and EDNS Client Subnet where supported.