성능 문제를 정의하는 기준
한 줄 정의
성능 문제는 단순히 느린 상태가 아니라, 정해진 사용량과 조건에서 응답 시간, 처리량, 오류율 같은 목표를 만족하지 못하는 상태다.
실무에서 왜 문제 되는가
- “느리다”는 표현만으로는 어떤 지표를 개선해야 하는지 알 수 없다.
- 평균 응답 시간은 괜찮아도 p95/p99가 나빠 사용자 일부가 장애를 겪을 수 있다.
- 재현 조건 없이 튜닝하면 개선 전후 비교가 불가능하다.
- 병목을 확인하지 않고 캐시, 인덱스, 스케일아웃을 적용하면 다른 장애를 만들 수 있다.
- 성능 개선은 정합성, 비용, 복잡도와 항상 trade-off가 있다.
동작 원리
- 사용자 영향이 있는 API나 작업을 정한다.
- 목표 지표를 정한다.
- 요청량, 데이터 크기, 동시 사용자 수, 외부 의존성을 고정한다.
- 현재 지표를 측정한다.
- 병목을 좁힌 뒤 하나씩 개선하고 다시 측정한다.
실무 판단 기준
| 상황 | 먼저 볼 기준 | 이유 |
|---|---|---|
| 사용자 API 지연 | p95/p99 latency | 일부 사용자 지연이 평균에 가려질 수 있다 |
| 대량 트래픽 처리 | throughput, error rate | 많이 처리해도 실패가 늘면 의미가 없다 |
| 배치 지연 | 처리 시간, 처리 건수, 재시작 가능성 | 사용자 API와 목표가 다르다 |
| 간헐적 timeout | dependency latency, pool usage | 외부 의존성과 자원 고갈을 같이 봐야 한다 |
| 개선 검증 | 개선 전후 같은 조건 | 조건이 다르면 비교가 무의미하다 |
자주 나는 실수
- 평균 latency만 보고 성능이 괜찮다고 판단한다.
- 목표 지표 없이 “빠르게 만들기”만 시도한다.
- 병목을 확인하기 전에 캐시부터 적용한다.
- 로컬 테스트 결과를 운영 성능으로 일반화한다.
- 개선 후 오류율, DB 부하, 비용 증가를 확인하지 않는다.
확인 방법
- 테스트: 같은 데이터 크기와 요청량으로 개선 전후를 비교한다.
- 로그: request id, endpoint, elapsed time, dependency elapsed time을 남긴다.
- 메트릭: p50/p95/p99 latency, throughput, error rate, saturation을 본다.
- 프로파일링: CPU, thread, DB query, external call 중 시간이 어디서 쓰이는지 확인한다.
장점과 한계
| 장점 | 한계 |
|---|---|
| 개선 목표가 명확해진다 | 지표 수집 체계가 필요하다 |
| 불필요한 튜닝을 줄인다 | 재현 환경을 만드는 비용이 든다 |
| 기술 질문에서 문제 해결 흐름을 설명하기 쉽다 | 운영 트래픽의 모든 변수를 통제하기는 어렵다 |
짧은 예제
목표:
- 주문 조회 API p95 < 300ms
- error rate < 0.1%
- 1분 평균 300 RPS
재현 조건:
- 주문 100만 건
- 사용자별 최근 주문 20건 조회
- Redis cache cold/warm 상태를 분리 측정성능 개선 전에는 “무엇을 얼마나 빠르게 할 것인지”와 “어떤 조건에서 측정할 것인지”를 먼저 정해야 한다.
핵심 요약
성능 문제는 느린 느낌이 아니라 목표 지표를 만족하지 못하는 상태다.
평균보다 p95/p99, error rate, saturation을 함께 봐야 한다.
개선 전에는 요청량, 데이터 크기, 캐시 상태, 외부 의존성 같은 재현 조건을 정한다.
병목을 확인하지 않은 최적화는 비용과 복잡도만 늘릴 수 있다.
좋은 성능 개선은 개선 전후를 같은 조건에서 숫자로 증명한다.
꼬리 질문
- 평균 latency만 보면 안 되는 이유는 무엇인가?
- 성능 개선 전 어떤 기준을 먼저 정해야 하는가?
- 캐시나 인덱스를 적용하기 전에 무엇을 확인해야 하는가?