작성일: 2026-05-18
성능P99응답시간
P95/P99 응답시간이란? 웹 서비스 성능 지표 완벽 이해
서비스 성능을 말할 때 "평균 응답시간 50ms"라고 하면 안심이 될 수 있습니다. 그런데 실제로 사용자 10명 중 1명은 5초를 기다리고 있을 수도 있습니다. 퍼센타일(Percentile) 기반 성능 지표가 필요한 이유입니다.
평균값의 함정
다음과 같은 10개의 응답시간(ms)이 있다고 가정합니다.
`` 20, 22, 18, 25, 21, 19, 23, 20, 18, 5000 `
- 평균: 218.6ms — 실제와 매우 다름
- 중앙값(P50): 21ms — 전형적인 사용자 경험 반영
- P95: 5000ms — 상위 5% 사용자의 경험
- P99: 5000ms — 상위 1% 사용자의 경험
평균은 이상치(outlier)에 심하게 왜곡됩니다.
P50, P95, P99의 의미
| 지표 | 의미 | 활용 |
|---|
| ------ | ------ | ------ |
| P50 | 전체 요청의 50%가 이 시간 이하 | 일반적인 사용자 경험 |
| P95 | 전체 요청의 95%가 이 시간 이하 | 대다수 사용자 경험 기준 |
| P99 | 전체 요청의 99%가 이 시간 이하 | 최악의 경험 탐지 기준 |
| P99.9 | 1,000명 중 1명의 경험 | 대규모 서비스 SLA 기준 |
Nginx 로그에서 응답시간 데이터 얻기
Nginx Combined Log Format의 기본 설정에는 응답시간이 포함되지 않습니다. $request_time 필드를 추가해야 합니다.
/etc/nginx/nginx.conf:
`nginx http { log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time';
access_log /var/log/nginx/access.log main; } `
$request_time: 클라이언트로부터 요청을 받은 순간부터 응답 전송이 완료될 때까지의 시간(초, 소수점 3자리)
커맨드라인으로 P95/P99 계산
`bash awk '{print $NF}' /var/log/nginx/access.log | sort -n > response_times.txt
TOTAL=$(wc -l < response_times.txt) P50=$(sed -n "$((TOTAL * 50 / 100))p" response_times.txt) P95=$(sed -n "$((TOTAL * 95 / 100))p" response_times.txt) P99=$(sed -n "$((TOTAL * 99 / 100))p" response_times.txt)
echo "P50: ${P50}s, P95: ${P95}s, P99: ${P99}s" `
성능 지표 해석 가이드
일반적인 웹 API 기준
| 상태 | P50 | P95 | P99 |
| ------ | ----- | ----- | ----- |
| 우수 | < 50ms | < 200ms | < 500ms |
| 양호 | < 200ms | < 500ms | < 1s |
| 주의 | < 500ms | < 1s | < 3s |
| 위험 | > 500ms | > 1s | > 3s |
P95는 괜찮은데 P99가 높다면?
특정 조건에서만 느린 요청이 발생한다는 신호입니다.
원인 후보:
- 콜드 스타트 (캐시 미스, JVM GC 일시 정지)
- DB 인덱스 미적용으로 특정 쿼리만 느림
- 외부 API 호출 타임아웃
- 연결 풀 고갈 시 대기
느린 요청만 별도 로그로 남기기
`nginx map $request_time $slow_log { ~^[1-9] 1; # 1초 이상 default 0; }
access_log /var/log/nginx/slow.log combined if=$slow_log; `
느린 요청만 분리해서 집중 분석하면 병목 원인을 빠르게 찾을 수 있습니다.
SLO와 에러 버짓
P99를 기반으로 SLO(Service Level Objective) 를 설정하면 에러 버짓(Error Budget)을 관리할 수 있습니다.
- SLO: "월간 P99 응답시간 500ms 이하를 99.9% 유지"
- 에러 버짓: 한 달(43,200분) 중 43.2분까지 허용
- 에러 버짓이 소진되면 새 기능 배포 대신 안정성 작업 우선
정리
평균 응답시간만 보는 것은 빙산의 일각만 보는 것입니다. P95와 P99를 함께 모니터링하면 일반 사용자와 최악의 경험을 하는 사용자를 구분해서 볼 수 있습니다. Nginx 로그에 $request_time`만 추가해도 서비스 성능의 실제 분포를 파악할 수 있습니다.