"느리다"의 원인을 가르는 두 축.
- 지연(latency) — 한 번 다녀오는 데 걸리는 시간 — RTT 대역폭(bandwidth) 단위 시간에 나르는 양 — bps
비유: 지연은 배송 시간, 대역폭은 트럭 크기
결정적 차이
- 대역폭 — 회선을 늘리면 는다 — 돈으로 해결된다
- 지연 — 빛의 속도와 거리에 묶인다 — 돈으로 해결되지 않는다
서울 ↔ 미국 왕복은 광속으로도 최소 110ms 1Gbps 로 올려도 이 시간은 그대로다
어느 쪽이 병목인지 가르기
작은 요청을 여러 번 보낸다 (API · 웹페이지 로딩)
- 지연이 지배한다. 왕복 횟수를 줄이는 것이 답
큰 파일 하나를 보낸다 (영상 · 백업)
- 대역폭이 지배한다. 회선을 늘리는 것이 답
웹 성능 문제의 대부분은 지연이다 — 그래서 요청 수를 줄이고, 병렬화하고, 가까운 곳에서 주는 것이 효과가 크다.
BDP — 얼마나 채워야 회선을 다 쓰나
BDP(Bandwidth-Delay Product) = 대역폭 × RTT
1Gbps · RTT 100ms → 125Mbit ≈ 12.5MB
- 전송 중인 데이터가 이만큼 '떠 있어야' 회선을 다 쓴다
- TCP 윈도우가 이보다 작으면 회선이 놀게 된다
"회선은 1Gbps 인데 실제로 50Mbps 밖에 안 나온다" 의 흔한 원인
계층별 진단 도구
ping example.com # 3계층 — 도달 여부와 RTT
mtr example.com # 홉별 지연·손실 (traceroute + ping)
ss -ti # 4계층 — RTT · 재전송 · 혼잡 윈도우
tcpdump -i eth0 port 443 -w a.pcap # 패킷 수준
curl -w "@fmt.txt" -o /dev/null -s https://example.com # 단계별 소요 시간
# fmt.txt — 어디서 시간이 새는지 나눠 본다
dns: %{time_namelookup}
tcp: %{time_connect}
tls: %{time_appconnect}
ttfb: %{time_starttransfer}
total: %{time_total}
"DNS가 느린가, 연결이 느린가, 서버가 느린가"를 이 한 줄로 가른다.
개선 방향
- 지연을 줄인다 — CDN(거리) · 연결 재사용(핸드셰이크 생략) · 요청 수 감소
- HTTP/2·3 멀티플렉싱 · 0-RTT
- 대역폭을 아낀다 — 압축(gzip·br) · 이미지 최적화 · 캐시로 재전송 자체를 없앤다
면접 함정
- ❌ "회선을 늘리면 빨라진다" → 지연이 병목이면 전혀 안 빨라진다.
- ❌ "ping이 낮으면 빠르다" → ICMP 지연일 뿐이다. TLS 핸드셰이크·서버 처리 시간은 별개다.
웹 성능에서 왕복 수가 지배한다
페이지 하나를 여는 데 필요한 왕복
DNS 조회 1 RTT
TCP 핸드셰이크 1 RTT
TLS 핸드셰이크 1~2 RTT (1.3 이면 1)
HTTP 요청·응답 1 RTT
─────────
최소 4 RTT
RTT 200ms 면 첫 바이트까지 800ms — 파일 크기와 무관하다
그래서 개선의 핵심이 "왕복 줄이기" 가 된다 — 연결 재사용, CDN, 0-RTT, 프리커넥트.
병목을 실측으로 가른다
# 같은 파일을 크기만 다르게 받아 본다
curl -w "%{time_total} %{size_download}\n" -o /dev/null -s https://example.com/1kb
curl -w "%{time_total} %{size_download}\n" -o /dev/null -s https://example.com/10mb
크기가 100배인데 시간이 거의 같다 → 지연이 지배한다
크기에 비례해 시간이 는다 → 대역폭이 지배한다
지연 예산
사람이 느끼는 기준
100ms 이하 즉각적으로 느낀다
1초 이하 흐름이 끊기지 않는다
10초 이상 사용자가 떠난다
네트워크 왕복 4번(800ms)을 쓰고 나면 서버 처리에 쓸 예산이 얼마 안 남는다