브라우저가 shop.example.com 같은 주소로 연결을 시작하면, 그 도메인 이름의 IP를 DNS로 찾는
조회가 먼저 일어납니다. 결론부터 말하면, 도메인→IP는 재귀 리졸버의 캐시와 여러 DNS 서버를
거치는 조회이고, 한 번 찾으면 TTL 동안 캐시에서 바로 답합니다.
조회 경로
처음 찾는 주소라면 조회는 이렇게 내려갑니다.
- 브라우저/앱 → OS 스텁 리졸버: 요청을 DNS 조회 서버(재귀 리졸버)로 전달만 합니다.
- 재귀 리졸버: 캐시에 없으면, 대신 끝까지 물어봅니다.
- 루트 → TLD: 루트와 TLD 서버는 답을 주지 않고 다음 서버를 알려주는 위임만 합니다.
- 권한 서버: 마지막으로 최종 IP(A 레코드)를 응답합니다.
즉 루트·TLD는 "캐시 미스"가 아니라 길을 안내하는 단계이고, 실제 답은 권한 서버가 줍니다.
캐시와 TTL
재귀 리졸버는 받은 답을 TTL(Time To Live) 동안 캐시해 둡니다. TTL은 "이 답을 몇 초 동안 믿어도 되는가"입니다. 그래서 같은 주소를 다시 조회하면 루트까지 갈 필요 없이 즉답합니다.
한 가지 더 있습니다. 리졸버는 최종 IP뿐 아니라 권한 서버의 위치(NS 위임) 도 따로, 대개 더 길게 캐시합니다. 그래서 짧은 IP 캐시(A)가 만료돼도 위임 캐시가 살아 있으면, 루트·TLD를 건너뛰고 권한 서버로 바로 다시 물어봅니다.
직접 조회해 보기
아래에서 바로 눌러볼 수 있습니다. 첫 화면은 콜드 조회 한 건이 채워진 상태입니다.
주소를 고르고 조회하세요
캐시가 있으면 빠르고, 비면 루트부터 다시 돕니다
주소를 골라 조회해 보세요.
다음 → ‘조회’해서 IP를 찾아보세요(캐시가 비어 4단계 콜드).
단순화한 시뮬레이션이며 실제 조회나 지연이 아닙니다. 예시 도메인은 문서용 예약 도메인(example.com/.net, RFC 2606), IP는 문서용 대역(192.0.2.0/24, RFC 5737)만 씁니다. 재귀 리졸버의 캐시 한 곳만 모델링하며 DNSSEC·부정 캐싱·복수 IP 등은 생략했습니다.
참고: RFC 1034·1035·9499(DNS), Google Public DNS
데모만 따로 보려면 전체 화면으로 열기.
- 조회: 캐시 상태에 따라 1단계(IP 캐시 히트) · 2단계(권한 직행) · 4단계(완전 콜드)로 갈립니다.
- IP 주소 캐시 시간(A TTL): 짧게 두면 카운트다운이 0이 되는 걸 보고, A만 만료된 상태를 만들 수 있습니다.
- 전체 캐시 비우기: A와 위임을 모두 지워 완전 콜드로 되돌립니다.
카드 아래 다음 → 안내를 따라가면, "느린 전체 조회 → 빠른 캐시 히트 → 권한 직행"을 순서대로 볼 수 있습니다.
처음엔 이 화면을 틀리게 그렸습니다
만들기 시작할 때는 네 단계를 전부 "캐시 히트/미스"로 칠했습니다. 루트에 물어보면 미스, TLD에 물어보면 미스, 권한 서버에서 드디어 히트. 그림은 깔끔했는데 DNS 동작이 아니었습니다.
루트와 TLD 서버는 답을 갖고 있지 않습니다. "그건 내가 모르니 저쪽에 물어봐라"라고 떠넘기는 것(위임)이지, 캐시를 뒤졌다가 못 찾은 게 아닙니다. 캐시가 실제로 생기는 곳은 재귀 리졸버 한 곳뿐이고요. 히트/미스로 칠하면 루트 서버가 전 세계 도메인을 캐시해 두고 있다는 인상을 줍니다. 정반대죠.
그래서 화면을 위임과 응답으로 다시 나눴습니다. TTL도 A와 NS 위임 두 개로 쪼갰습니다. 처음엔 하나로 뒀는데, 그러면 위의 2단계(권한 직행)가 아예 만들어지지 않습니다. A만 먼저 만료되고 위임은 살아 있는 구간이 있어야 나오는 상태라서요. 지금 A가 15초, 위임이 120초인 건 그 구간을 기다려서 볼 수 있게 하려고 고른 값입니다.
결과 해석
- 1단계(IP 주소 캐시 히트): 가장 빠름. 리졸버 캐시가 바로 답했습니다.
- 2단계(권한 서버 위치 캐시 히트): A는 만료됐지만 위임이 살아 권한 서버로 직행.
- 4단계(완전 콜드): 캐시가 비어 루트부터 전체 경로.
같은 결과라도 캐시 상태에 따라 걸리는 단계가 다르다는 것 — 이게 DNS 캐시와 TTL의 핵심입니다.
실제 조회와 비교하기
데모는 정해진 장면을 보여주지만 실제 컴퓨터에서는 dig로 응답과 TTL을 볼 수
있습니다.
# 현재 설정된 재귀 리졸버에 A 레코드 조회
dig example.com A
# 루트부터 위임 경로를 따라가며 조회
dig +trace example.com A
첫 명령의 ANSWER SECTION에는 받은 IP와 남은 TTL이 표시됩니다. 바로 다시 실행하면
같은 리졸버 캐시에서 TTL이 줄어든 답을 볼 수 있습니다. +trace는 로컬 리졸버의
일반 재귀 조회를 그대로 재현하는 명령이 아니라, 도구가 루트부터 권한 서버까지
직접 따라가며 위임을 관찰하는 방식입니다. 둘의 시간이 다르다는 사실만으로 평소
DNS가 느리다고 판단하면 안 됩니다.
직접 재 본 값 — TTL은 진짜로 초 단위로 줄어듭니다
글을 쓰면서 실제로 측정한 값입니다. 2026-08-08 09:37 KST, 리눅스 워크스테이션
한 대에서 dig로 example.com의 A 레코드를 5초 간격으로 조회했습니다.
| 조회 시점 | 남은 A TTL |
|---|---|
| 처음 | 63초 |
| +5초 | 58초 |
| +10초 | 53초 |
| +15초 | 48초 |
5초가 지날 때마다 정확히 5씩 줄었습니다. TTL은 비유가 아니라 리졸버가 실제로 세고 있는 초라는 뜻입니다. 0이 되면 그 답은 버려지고 다음 조회는 다시 물어봐야 합니다.
같은 순간에 위임(NS) 레코드의 TTL도 재 봤습니다.
| 레코드 | 남은 TTL |
|---|---|
example.com A | 63초 |
example.com NS | 26,856초 (약 7시간 27분) |
본문에서 "위임은 대개 더 길게 캐시된다"고 한 부분이 이 두 줄입니다. A가 만료돼도 NS는 한참 살아 있으므로, 그 사이의 조회는 루트·TLD를 건너뛰고 권한 서버로 바로 갑니다. 데모의 2단계가 이 상황입니다.
캐시가 있을 때와 없을 때의 조회 시간
같은 방법으로 도메인 세 개를 연달아 두 번씩 조회한 결과입니다(같은 시각, 같은 장비).
| 도메인 | 1회차 | 2회차 | 받은 A TTL |
|---|---|---|---|
rfc-editor.org | 59ms | 0ms | 299초 |
ripe.net | 13ms | 1ms | 299초 |
iana.org | 4ms | 1ms | 3,047초 |
읽을 때 주의할 점이 두 가지 있습니다. 첫째, 1회차가 "캐시가 완전히 빈 상태"라는
보장은 없습니다. iana.org가 처음부터 4ms인 것은 이미 어딘가에 캐시돼 있었다는
뜻이고, 받은 TTL이 3,047초라는 것도(원래 TTL이 그보다 컸다면) 이미 시간이 흐른
답이라는 신호입니다. 둘째, 이 장비의 조회 대상은 127.0.0.53, 즉 로컬 스텁
리졸버입니다. 그래서 0~1ms는 "재귀 리졸버가 빨랐다"가 아니라 내 컴퓨터 안에서
답했다는 뜻입니다.
그래도 방향은 분명합니다. 캐시에 있으면 밀리초 이하, 없으면 수십 밀리초. 페이지 하나에 여러 도메인이 섞여 있으면 이 차이가 그대로 첫 화면 지연에 얹힙니다.
존재하지 않는 이름의 결과도 일정 시간 캐시할 수 있습니다. 이를 부정 캐싱이라고 하며, 오타 난 이름을 반복해서 루트부터 조회하지 않게 합니다. 데모는 처음 배우는 흐름을 짧게 유지하려고 성공한 A 레코드와 NS 위임만 보여줍니다.
흔한 오해 — "TTL을 60초로 줄이면 60초 만에 바뀐다"
서버를 옮길 때 자주 하는 계산입니다. TTL을 60초로 낮춰 뒀으니 전환하고 1분이면 모두가 새 IP를 볼 것이라는 기대죠. 실제로는 그렇게 되지 않는 경우가 많습니다.
이유는 캐시가 한 곳이 아니기 때문입니다. 위 측정만 봐도 답이 나온 곳은 권한 서버가 아니라 내 컴퓨터 안의 스텁 리졸버였습니다. 실제 경로에는 최소한 이만큼이 줄줄이 있습니다.
- 브라우저 자체 캐시
- OS의 스텁 리졸버 캐시(위 측정의
127.0.0.53) - 통신사·회사의 재귀 리졸버 캐시
- 그 앞단에 있을 수 있는 또 다른 전달(forwarding) 리졸버
여기에 더해, TTL을 낮추는 변경 자체도 옛 TTL이 만료된 뒤에야 퍼집니다. 원래 TTL이 1시간이었다면, TTL을 60초로 바꾼 사실이 모두에게 알려지기까지 최대 1시간이 걸립니다. 그래서 전환 계획은 "옮기기 직전에 TTL을 줄인다"가 아니라 **"옛 TTL보다 더 앞서 줄여 둔다"**가 되어야 합니다.
그리고 규격을 지키지 않고 TTL을 무시하거나 자기 마음대로 늘려 잡는 리졸버도 존재합니다. 그래서 실무에서는 "TTL이 지나면 끝"이 아니라 옛 주소를 한동안 함께 살려 두는 편이 안전합니다.
어디까지 믿고 봐야 하는지
이 글에는 성격이 다른 세 가지가 섞여 있습니다. 구분해서 읽어야 오해가 없습니다.
- 데모의 숫자 — 원리를 보여주기 위한 단순화한 시뮬레이션입니다. 실제 조회도
실제 지연도 아닙니다. 예시 도메인은 문서용 예약 도메인(
example.com/example.net), IP는 문서용 대역(192.0.2.0/24)만 씁니다. 재귀 리졸버 캐시 한 곳만 모델링하며 DNSSEC·부정 캐싱·복수 IP 등은 생략했습니다. - 위 표의 측정값 — 2026-08-08 09:37 KST에 리눅스 워크스테이션 한 대에서 잰 실제 관측값입니다. 다만 장비 한 대, 네트워크 한 곳, 한 시점의 값이라 일반적인 성능 지표로 쓸 수는 없습니다. 같은 명령을 지금 실행하면 TTL도 조회 시간도 다르게 나옵니다 — 그게 정상입니다.
- 본문의 설명 — 아래 RFC 문서에 정의된 동작을 풀어 쓴 것입니다.
데모에 없는 것도 분명히 해 둡니다. DNSSEC 검증, EDNS 옵션, 여러 IP 중 하나를 고르는 정책, CNAME 체인, DoH·DoT 같은 암호화 전송은 다루지 않습니다.