OneWebDesk

사이트가 느릴 때: TTFB 원인 진단과 개선 순서

첫 바이트까지의 시간(TTFB)이 늘어지는 원인 — DNS·TLS·서버·DB — 을 구간별로 진단하고 줄이는 법.

“사이트가 느려요”라는 문제의 절반은 브라우저가 첫 바이트를 받기도 전에 이미 결정됩니다. TTFB(Time To First Byte)는 사용자가 주소를 입력한 순간부터 서버 응답의 첫 바이트가 도착할 때까지 걸린 시간으로, 이 시간이 길면 그 뒤에 아무리 이미지를 최적화해도 체감 속도는 나아지지 않습니다. 구글 기준으로 200ms 이하면 우수, 800ms를 넘으면 나쁨입니다. 1초가 넘는 TTFB는 거의 항상 고칠 수 있는 원인이 있습니다.

중요한 것은 TTFB가 하나의 숫자가 아니라 여러 구간의 합이라는 점입니다. DNS 조회 → TCP 연결 → TLS 핸드셰이크 → 서버 처리(생각하는 시간) → 첫 바이트 전송이 순서대로 쌓입니다. 어느 구간이 느린지 모르고 캐시 플러그인부터 설치하는 것은 진단 없이 약을 먹는 것과 같습니다. 이 가이드는 구간별로 측정하고, 구간별 범인을 찾고, 효과가 큰 순서대로 고치는 절차를 정리합니다. 지금 내 사이트의 구간별 시간을 바로 보고 싶다면 응답 시간 측정 도구에 URL을 넣어 DNS·연결·TLS·대기 시간을 분해해서 확인하세요.

TTFB에 포함되는 것과 포함되지 않는 것

먼저 범위를 정확히 해야 엉뚱한 곳을 고치지 않습니다. TTFB는 다음 다섯 구간의 합입니다.

  1. DNS 조회 — 도메인을 IP 주소로 변환하는 시간.
  2. TCP 연결 — 서버와 3-way 핸드셰이크를 맺는 시간(왕복 1회, RTT에 비례).
  3. TLS 핸드셰이크 — HTTPS 암호화 협상(보통 왕복 1~2회 추가).
  4. 서버 처리 시간 — 요청을 받고 HTML을 만들 때까지 서버가 “생각하는” 시간. DB 쿼리, 템플릿 렌더링, 외부 API 호출이 전부 여기에 들어갑니다.
  5. 첫 바이트 전송 — 만들어진 응답의 첫 조각이 네트워크를 건너오는 시간.

반대로 TTFB에 포함되지 않는 것: HTML 다운로드 나머지, 이미지·JS·CSS 로딩, 렌더링, 자바스크립트 실행. 즉 TTFB가 180ms인데 페이지가 5초 걸린다면 범인은 서버가 아니라 프런트엔드 쪽입니다. 그런 경우에는 페이지 용량 분석으로 리소스 무게를, 압축 적용 확인으로 gzip/brotli 적용 여부를 먼저 점검하는 것이 맞습니다.

구간별로 측정하기 — curl 한 줄이면 충분

터미널이 있다면 curl-w(write-out) 옵션으로 모든 구간을 한 번에 잴 수 있습니다.

curl -o /dev/null -s -w "DNS:        %{time_namelookup}s
TCP 연결:    %{time_connect}s
TLS 완료:    %{time_appconnect}s
첫 바이트:   %{time_starttransfer}s
전체:        %{time_total}s
" https://example.com/

각 값은 누적 시간이므로 구간별 소요는 앞 값을 빼서 계산합니다.

  • DNS 구간 = time_namelookup
  • TCP 구간 = time_connecttime_namelookup
  • TLS 구간 = time_appconnecttime_connect
  • 서버 처리(핵심) = time_starttransfertime_appconnect

터미널이 없거나 여러 지역에서의 체감을 보고 싶다면 응답 시간 측정 도구가 같은 분해 결과를 브라우저에서 보여줍니다. 측정은 3~5회 반복해 중간값을 보세요. 첫 요청은 DNS 캐시·서버 캐시가 비어 있어 항상 느리게 나옵니다.

구간별 범인 찾기

느린 구간흔한 원인대표 처방
DNS (> 100ms)느린 네임서버, TTL이 너무 짧아 캐시가 안 됨, CNAME 체인이 김애니캐스트 DNS 제공자(Cloudflare·Route 53 등)로 이전, CNAME 단계 축소
TCP (> 100ms)서버가 사용자와 물리적으로 멀어 RTT가 큼CDN 도입 또는 사용자와 가까운 리전으로 서버 이전
TLS (> 150ms)세션 재사용(session resumption) 미설정, TLS 1.2 풀 핸드셰이크, 원거리 서버TLS 1.3 활성화, 세션 티켓/재개 켜기, OCSP 스테이플링, CDN 종단
서버 처리 (> 300ms)페이지 캐시 없음, 인덱스 없는 DB 쿼리, 서버리스 콜드 스타트, 저사양 공유 호스팅전체 페이지 캐시, 쿼리 최적화·인덱스, 워밍업/프로비저닝, 호스팅 업그레이드
첫 바이트 전송서버가 응답 전체를 만든 뒤에야 전송 시작(버퍼링)스트리밍/조기 flush, 응답 압축(전송량 축소)

경험적으로 TTFB가 800ms를 넘는 사이트의 원인 1위는 서버 처리 시간입니다. DNS·TCP·TLS는 다 합쳐도 보통 200~300ms 안쪽이고, 나머지는 전부 서버가 HTML을 만드느라 쓰는 시간입니다.

효과 큰 순서대로 고치기

  1. 전체 페이지 캐시(효과 최대). 매 요청마다 DB를 두드려 HTML을 새로 만드는 대신, 완성된 HTML을 저장해 뒀다가 그대로 내보냅니다. WordPress라면 캐시 플러그인, 직접 만든 앱이라면 리버스 프록시 캐시(nginx·Varnish)나 정적 생성(SSG). 서버 처리 시간이 수백 ms에서 한 자릿수 ms로 줄어듭니다.
  2. DB 인덱스와 느린 쿼리 제거. 캐시가 비었을 때(로그인 사용자, 캐시 미스)도 빨라야 합니다. 느린 쿼리 로그를 켜고 100ms 넘는 쿼리에 인덱스를 추가하세요.
  3. Keep-Alive와 HTTP/2·HTTP/3. 연결을 재사용하면 두 번째 요청부터 TCP·TLS 비용이 사라집니다. HTTP/3(QUIC)는 핸드셰이크 왕복 자체를 줄입니다.
  4. CDN. 사용자가 여러 나라에 있다면 물리 거리(RTT)는 코드로 못 줄입니다. CDN 엣지가 TLS를 대신 종단하고 캐시된 HTML까지 내보내면 해외 TTFB가 극적으로 줄어듭니다.
  5. 호스팅 업그레이드. 위를 다 해도 서버 처리 시간이 안 줄면 CPU가 느리거나 이웃이 많은 공유 호스팅일 가능성이 큽니다. 이때는 코드가 아니라 서버를 바꾸는 게 답입니다.

실전 예: 1.4초짜리 WordPress를 180ms로

실제 진단 흐름을 그대로 따라가 보겠습니다. 어느 WordPress 블로그의 TTFB가 1.4초였습니다.

구간개선 전개선 후
DNS35ms35ms
TCP 연결40ms40ms
TLS 핸드셰이크85ms60ms (TLS 1.3)
서버 처리1,240ms45ms
합계(TTFB)약 1.4초약 180ms

측정 결과 DNS·TCP·TLS를 합쳐도 160ms — 네트워크는 멀쩡했습니다. 1.24초가 전부 서버 처리, 즉 PHP가 매 요청마다 테마 렌더링과 수십 개의 DB 쿼리를 실행하는 시간이었습니다. 페이지 캐시 플러그인 하나(WP Super Cache 계열)를 설치해 완성 HTML을 디스크에서 바로 내보내게 하자 서버 처리 시간이 45ms로 떨어졌고, TLS 1.3을 켜서 핸드셰이크도 조금 줄었습니다. 코드 수정 없이 TTFB가 1.4초 → 180ms. 진단을 먼저 했기에 이미지 최적화 같은 엉뚱한 작업에 시간을 쓰지 않은 것이 핵심입니다.

개선 후에는 TTFB 이후 구간도 점검하세요. 압축 적용 확인으로 HTML·CSS·JS에 brotli/gzip이 걸려 있는지, 페이지 용량 분석으로 전체 전송량이 적정한지 보면 첫 바이트 이후의 체감 속도까지 잡을 수 있습니다.

자주 묻는 질문

TTFB는 몇 ms 이하여야 하나요?
구글 web.dev 기준으로 800ms 이하가 '개선 필요' 경계이고, 200ms 이하면 우수입니다. 정적 파일이나 캐시된 HTML은 100ms 안쪽도 흔합니다. 800ms를 넘는다면 거의 확실히 서버 처리 시간이나 물리 거리에 고칠 수 있는 문제가 있습니다.
TTFB가 빠른데도 사이트가 느려요. 왜죠?
TTFB는 첫 바이트까지의 시간만 잽니다. 이미지·자바스크립트·CSS 다운로드와 렌더링은 포함되지 않습니다. TTFB가 200ms대인데 페이지가 수 초 걸린다면 리소스 용량과 압축, 렌더링 차단 스크립트를 점검해야 합니다. 페이지 용량 분석과 압축 적용 확인 도구로 먼저 확인해 보세요.
캐시 플러그인만 설치하면 TTFB가 무조건 빨라지나요?
익명 방문자에게 캐시된 HTML을 내보낼 수 있을 때만 효과가 큽니다. 로그인 사용자, 장바구니가 있는 쇼핑몰 페이지, 개인화된 화면은 캐시를 우회하므로 DB 쿼리 최적화와 호스팅 성능이 여전히 중요합니다. 또 캐시 만료 직후의 첫 요청(캐시 미스)은 여전히 느리므로 원본 성능 자체도 함께 개선해야 합니다.
CDN을 쓰면 TTFB가 얼마나 줄어드나요?
사용자와 원본 서버가 멀수록 효과가 큽니다. 예를 들어 서울 서버를 미국 사용자가 접속하면 TCP+TLS만으로 왕복 300ms 이상 쌓일 수 있는데, CDN 엣지가 근처에서 TLS를 종단하고 캐시된 HTML까지 내보내면 이 비용이 수십 ms로 줄어듭니다. 반대로 사용자와 서버가 같은 나라라면 체감 개선은 작을 수 있습니다.
측정할 때마다 TTFB 값이 크게 달라집니다.
정상입니다. 첫 측정은 DNS 캐시와 서버 캐시가 비어 있어 느리고, 이후 측정은 캐시 덕에 빨라집니다. 서버리스 환경이라면 콜드 스타트로 첫 요청만 수백 ms 느릴 수도 있습니다. 3~5회 반복 측정해 중간값을 기준으로 삼고, 첫 방문자 경험을 보려면 캐시가 빈 상태의 값도 따로 기록하세요.

이 가이드와 함께 쓰면 좋은 도구

관련 가이드