Module 02 · Lesson 2 of 14Free
DNS: how domain names resolve to IP addresses
- Level
- Beginner
- Topic
- Networking, APIs and load balancing
- Reading time
- 15 min
When you finish this page you can
- Trace a domain lookup from a client through a resolver to the authoritative answer.
- Explain how cached DNS answers affect latency, outages and address changes.
- Choose a TTL and a safe sequence for changing a service’s address.
- Distinguish DNS failures from failures after a connection begins.
Builds on 2 lessons
Start with Module 01, lesson 215 minVideo lesson · coming soon
The address changed, not every answer
moves its public entry point to a new IP address before a festival sale. Ten minutes later, some customers reach it. Others still reach the old address.
The team changed one record. Why didn’t every customer start using the new address?
In this lesson’s scenario, Kartly has four app servers behind a . DNS returns the load balancer’s public address, not an address for each app server.
Kartly changes its DNS answer at noon. A resolver cached the old answer one minute earlier, with permission to keep it for one hour. Does the edit immediately replace that cached answer?Show answer
DNS, the Domain Name System, lets clients look up information by name. Its distributed design separates the published answer from temporary copies held elsewhere. That separation explains both its speed and Kartly’s migration problem.1
Diagram not drawn yet: dns-lookup-before-connection.svg
A browser asks a recursive resolver for Kartly’s address. On a cache miss, the resolver asks the root, the top-level domain servers and Kartly’s authoritative servers. The browser then connects directly to the returned load balancer address, which forwards requests to four app servers.
All addresses and timings below are examples. Names ending in .example are fictional; the hierarchy shown is a teaching model, not a public lookup to run.
The next question is who owns the answer, and who merely remembers it.
One name outlives one address
Imagine shipping 192.0.2.10 inside Kartly’s mobile app. It works until the team moves the entry point. Every installed app now needs another way to discover the replacement.
A name such as kartly.example gives the app a stable reference. The address can change without changing that reference. This separation is a core DNS design goal.1
The answer is stored as a record: a typed piece of information associated with a name.
| Record type | Meaning | Kartly example |
|---|---|---|
| A | Name to IPv4 address | kartly.example → 192.0.2.10 |
| AAAA | Name to IPv6 address | An IPv6 address for the same entry point |
| CNAME | Name to another name | shop.kartly.example → kartly.example |
A CNAME target is a name, not an IP address. Address resolution must eventually find an address record.
For this scenario, Kartly publishes an A record directly. An alias would be useful if several names needed to follow one target. It would also create another record to inspect during troubleshooting.
The record answers “where?”. It does not contain the product page. That distinction builds on the request lifecycle: finding an address comes before contacting the application.
Now we need a way to find the record without copying every domain’s records onto every phone.
The resolver follows the hierarchy
The client asks a to find the answer. The resolver does the lookup work on the client’s behalf.
An serves the published records for a particular part of the namespace. A resolver’s cached copy is not the authority.1
Here is an empty-cache lookup in our fictional hierarchy:
- The client asks its resolver for the A record of
kartly.example. - The resolver asks a root server. It receives a referral towards the
.exampleservers. - Those servers refer it towards Kartly’s authoritative nameservers.
- Kartly’s authoritative server returns
192.0.2.10. - The resolver returns the answer to the client and it.
A referral points the resolver towards another nameserver; it is not the final address. The resolver follows these referrals rather than making the browser do so.1
For our scenario, these parts have distinct responsibilities:
| Part | Responsibility | Talks to | State | If unavailable |
|---|---|---|---|---|
| Client | Request an address | Resolver | Possibly a local cached answer | Cannot complete this lookup |
| Resolver | Find and cache answers | Client and nameservers | Temporary answers | Clients need another working resolver |
| Root and parent servers | Refer queries down the hierarchy | Resolver | Delegation records | An uncached lookup may fail |
| Kartly authority | Serve Kartly’s records | Resolver | Published records | Existing cached answers may still work |
| Load balancer | Accept application traffic | Client and app servers | Backend configuration | Address lookup can succeed, but the page fails |
This table describes our deployment model, not a requirement to run each role on one machine.
Kartly’s configuration write path is separate: an operator changes the record through its DNS provider. The authority then serves the updated record. Existing cached answers remain until their old lifetimes expire.
So a successful configuration change is not proof that every customer sees the new address.
Caching avoids repeating the lookup
Suppose the resolver already knows Kartly’s address. It can answer without repeating the hierarchy walk.
The record’s , or , gives a cache lifetime in seconds. A resolver may reuse the answer during that interval. Changing the source does not reset the lifetime of answers already cached elsewhere.
Consider this illustrative resolver entry:
| Lookup | Cached value | Received | Expires | |
|---|---|---|---|---|
kartly.example, A |
192.0.2.10 |
11:59 | 3,600 seconds | 12:59 |
Kartly publishes 198.51.100.20 at noon. Under these assumptions, this resolver can still answer with 192.0.2.10 at 12:30.
Another resolver first asks at 12:01. It receives the new address. Neither resolver needs to be broken for customers to see different answers.
Diagram not drawn yet: dns-two-resolvers-one-change.svg
Kartly changes its authoritative A record at 12:00. Resolver A cached the old address at 11:59 with a 3,600-second TTL and retains it until 12:59. Resolver B asks at 12:01 and receives the new address. At 12:10 their answers differ.
Show the cost of a miss
Assume the following timings for one example lookup. These are not internet-wide estimates.
Reach the resolver
Client-to-resolver round trip = 10 ms
A can finish after this exchange.
Follow three uncached stages
3 sequential exchanges × 30 ms = 90 ms
In this simplified model, the root, parent and authority each require one exchange.
Compare the two paths
Cold lookup: 10 ms + 90 ms = 100 ms; cached lookup: 10 ms
The cache removes 90 ms here. These figures exclude connecting to Kartly and fetching the page.
The example assumes no retries, aliases or cached referrals. Its lesson is the dependency chain: each uncached stage waits for the previous answer.
Caching reduces that work, but it also delays how quickly an address change becomes visible.
A shorter TTL buys faster change
Kartly now needs a policy, not just a record.
For this scenario, the team can keep both entry points working during a planned migration. It wants most standard cache lifetimes to clear within minutes after cutover.
How long should Kartly let resolvers reuse its public address?
Use a one-day TTL.
A resolver can reuse an answer for a full day. This avoids repeated lookups, but an address published just before cutover can remain cached throughout that day.
Use a 300-second TTL for the migration window.
An answer received just before cutover has up to five minutes left under normal TTL-based caching. Resolvers must refresh more often, increasing dependence on working DNS lookups.
Disable answer caching with a zero TTL.
A zero TTL prevents ordinary reuse of the answer. This removes that caching benefit and makes repeated lookups depend on available DNS service; it still does not move an existing connection.
Why this choice
Choose five minutes for this migration window. It gives Kartly time to observe a cutover without keeping the old address in ordinary caches all day.
This is not a universal setting. A stable address with no urgent migration need can use a longer TTL. A tighter recovery target may justify a shorter one.
The tradeoff follows from reuse: fewer refreshes mean fewer opportunities to observe a new value. More refreshes mean more lookup work.
TTL-based reuse and zero-TTL behavior are defined by DNS. Existing connections are a separate concern.
Count queries, not page views
Assume 1,000 independent resolver caches continuously need this one record. Each refreshes once per TTL interval. Ignore eviction, retries and additional record types.
With a five-minute lifetime
1,000 caches ÷ 300 seconds ≈ 3.3 refreshes per second
This is estimated traffic reaching the authority for this record.
With a one-minute lifetime
1,000 caches ÷ 60 seconds ≈ 16.7 refreshes per second
Refresh traffic becomes five times larger in this model.
Do not apply this formula directly to Kartly’s request rate. Many requests can reuse one cached address.
The team has chosen a shorter TTL. It still must apply that choice before the migration, not during the outage.
Change the address before retiring it
Return to the opening failure. Suppose Kartly lowered its TTL at noon and immediately removed the old entry point.
A resolver that cached the previous one-hour answer at 11:59 never received the new TTL. Its users can still be sent to the retired address until 12:59. Lowering the TTL now cannot shorten that existing entry.
For the scenario, use this sequence:
- Prepare the new entry point. Confirm that it serves the same Kartly application.
- Lower the old record’s TTL. Leave its address unchanged.
- Wait out the previous TTL. Existing standard cache entries need time to expire.
- Publish the new address. Keep the old entry point serving traffic.
- Observe both entry points. Investigate continued old-address traffic before retiring it.
Waiting after lowering the TTL is the important ordering rule. Published migration procedures use this same sequence.
Do not treat TTL expiry as a promise that every connection moved. A long-lived connection can remain attached to its original endpoint.
For Kartly, DNS should locate the load balancer. Individual app-server replacement belongs behind that entry point, covered in Load balancers.
That boundary prevents an ordinary app-server restart from becoming a public DNS migration.
Diagnose the failure at its boundary
In this scenario, use two questions:
- Did the client obtain the expected address?
- After obtaining it, could the client reach Kartly?
A wrong address suggests inspecting records and caches. An expected address shifts the investigation towards the endpoint and connection path.
Also distinguish two DNS outcomes. NXDOMAIN means the queried name does not exist. A name can exist without having the requested record type. Those are different negative answers.2
Negative answers can be cached too. Suppose a customer looks up sale.kartly.example before Kartly creates it. Publishing the record later does not necessarily clear that customer’s resolver’s cached nonexistence answer. This is .2
For a launch, create the name before customers need it. Otherwise, the first failed visits can outlive the configuration mistake.
Try it yourself
Run this in a Bash-compatible shell against a public example site:
curl --silent --show-error --output /dev/null \
--write-out 'lookup_seconds=%{time_namelookup}\n' \
https://example.com/Illustrative output:
lookup_seconds=0.018742The value measures seconds from the start until name resolution completed. It does not measure the page’s download time.
Repeat it, but do not assume a faster second result proves a particular cache answered. This measurement alone cannot identify the cache layer. On a proxy-managed network, it may not represent direct resolution of the destination.
Where this shows up
- Design: a fast product catalog page: lookup time can precede the work that produces a fast page.
- Design: a URL shortener for millions of users: a stable public name must survive infrastructure changes.
DNS gives the client an address; HTTP and HTTPS explain the conversation that follows.
Common mistakes
Treating an edit as a global cache update. Plan for old and new answers to coexist until existing cache lifetimes end.
Using a CNAME as an address record. Its value must be another name, not the replacement IP address.
Calling every lookup failure “the name doesn’t exist”. A negative existence answer differs from a missing record type. Diagnose the actual outcome before changing records.2
Check your understanding
A resolver cached Kartly’s old address at 09:00 with a 600-second TTL. Kartly changes the address at 09:02. Under the stated cache model, when does that cached entry expire?Show answer
Kartly lowers a one-hour TTL to one minute and immediately shuts down the old endpoint. Why can some customers still fail?Show answer
Kartly’s authority is briefly unavailable. Why might one customer still resolve the address while another cannot?Show answer
A new sale hostname was queried before Kartly created it. The record now exists, but one resolver still reports NXDOMAIN. What should you inspect?Show answer
Summary
- Customers can see different addresses after an edit because DNS caches expire independently.
- A resolver finds answers; authoritative nameservers publish the records.
- A and AAAA records contain addresses; point to another name.
- Shorter TTLs allow earlier refreshes but require more lookup work.
- Lower TTLs before a migration, wait out the previous lifetime, and keep the old endpoint available during cutover.