
유저: 실습 기능이 너무 느린것 같아요.
개발팀: 저희는 재연이 안되어서... 혹시 어떻게 하셨나요?
이런 일이 벌써 몇 번째였다. 항상 유저가 먼저 문제를 발견하고, 리포트해주기를 기다리는 수동적인 상황에 놓여있었다. 서비스에 문제가 생겨도 개발자는 알 수 없는 구조였다.
그러다 보니 자연스레 유저가 서비스를 신뢰하지 못하게 되고, 개발자들은 예측이 안되는 이슈에 예정된 일을 내팽개치고 달려나와 해결해야 하는 상황에 놓이게 되었다.
더 큰 문제는 개선 작업 후에도 마찬가지였다. 데이터베이스 쿼리를 최적화하고, 캐시를 도입해도 "정말 빨라졌나?"라는 의문만 남긴채 쌓인 이슈를 처리하러 갈 뿐이었다.
개선 효과를 수치적으로 증명할 방법이 없기 때문이었는데, 이는 팀 내 개발자들의 동기부여에도 악영향을 미치고 있었다.
메트릭부터, 빠르게 구축하자
APM(Application Performance Monitoring) 시스템을 한번에 도입하려 했지만, 복잡한 인프라 세팅과 러닝 커브가 부담스러웠다. 우리에게 당장 필요한 현재 서버 상태를 대략적으로라도 파악할 수 있는 메트릭부터 구축하기로 결정했다.
메트릭만 제대로 도입해도 위에서 설명한 문제들을 해결 할 수 있다
- 실시간 서비스 상태 파악: 개발자가 먼저 서비스 이상을 탐지할 수 있음
- 성능 개선 효과 측정: 수치로 증명 가능한 개선 결과
- 문제 구간 식별: 어떤 엔드포인트에서 문제가 발생하는지 즉시 확인
수집하기
아래 두가지 메트릭만 우선 수집하기로 결정했다.
http_requests_total (요청 수)
- 라벨: path, method, status_code
- 엔드포인트별 트래픽 패턴과 에러율 추적
http_duration (요청 시간)
- 라벨: path, method
- 각 요청의 처리 시간 분포 측정
현재 우리의 대부분 MSA는 FastAPI로 구현되어 있는데, http 요청 메트릭을 기록하는 Middleware를 구현하였다
def setup_apm(app: FastAPI, service_name: str, version: str) -> MetricsManager:
middleware = APMMiddleware(service_name, version)
app.add_middleware(BaseHTTPMiddleware, dispatch=middleware)
@app.get(
"/metrics",
include_in_schema=False,
response_class=PlainTextResponse,
tags=["monitoring"],
)
async def metrics_endpoint() -> PlainTextResponse:
return PlainTextResponse(
middleware.metrics.generate_metrics(),
media_type="text/plain; version=0.0.4; charset=utf-8",
)
return middleware.metrics
시각화 (대시보드 구축)
시각화는 grafana를 이용했다.
grafana는 JSON 기반 대시보드 설정이 가능해서, claude와 대화 몇번 주고받으면서 대시보드를 완성시켰다

Request Per Seconds.
서비스 전체의 트래픽 패턴을 모니터링한다. 어느 기능에 요청이 몰리는지 파악할 수 있다.
Request Duration (99p/90p/50p)
응답 시간의 백분위수를 추적하는 가장 중요한 메트릭이다
- 50p (median): 일반적인 사용자 경험
- 90p: 대부분의 사용자 경험
- 99p: 최악의 사용자 경험
Slowest Endpoint
가장 느린 엔드포인트가 무엇인지 알 수 있다. 성능 개선이 필요한 기능의 우선순위를 정하는 데 도움이 된다.
배포 하자마자 문제발견

배포하고 1시간만에 안되는 조회 Endpoint에서 99p와 90p, 50p의 격차가 넓은것을 확인했다.
외부호출이 있는 엔드포인트 였는데 특정 상황에 지연이 발생하고 있어서, 내일 해결해봐야 겠다.
느낀점
- 이걸 왜 이제 했을까..
- 평균은 문제를 숨긴다
- 대시보드를 세팅할때 처음에는 Request Duration의 평균값만 기록하였는데, 모든 기능의 지연시간이 고만고만해보여서 아무런 문제가 없는줄 알았다.
- 의심스러워서 99p/90p/50p등의 백분위수를 도입하고 다니 평균에 가려져있던 문제들이 드러나게 되었다.
- 수치화는 개발자에게 동기부여를 준다
- 대부분의 개발자는 목표지향적인 성격을 가지고 있다고 생각한다
- 그런 그들에게 OO기능 50% 성능 개선과 같은 정량적 목표를 부여한다면 달성했을때 더 큰 보람을 스스로 느낄 것이다