개발 기록Dev Log
← 목록

500ms는 어디서 샜을까 — 서버는 25ms인데

홈·프로필 API가 500ms씩 느린 원인을 추적하다 origin은 25ms로 결백함을 확인하고, 남은 용의자 Cloudflare 엣지 구간까지 좁힌 과정.


1. 왜

경진대회 출품 목표로 서비스를 만들었다. 제출은 마쳤지만, 완성 후 홈과 프로필 조회에서 데이터가 느리게 오는 걸 확인했다. 페이지는 바로 보이는데 "데이터 조회중입니다..." 표시가 대략 1~2초 정도 화면에 표시됐다. 그래서 원인을 추적하기 시작했다.

2. 첫 단서: 균일하게 느린 API들

네트워크 탭을 확인해보니 홈과 프로필 조회 시 사용하는 api 응답이 500ms 정도로 비슷한 응답 속도를 보이고 있었다. 서로 다른 API가 각자 다른 쿼리를 하는데 시간은 비슷한게 이상했다. 쿼리 자체가 문제라면 API마다 시간이 달라야 정상아닌가 의심이 들었다.

3. 의심

혹시 모든 api가 통과하는 authguard에서 병목이 발생하는지 확인했지만 JWT 서명 검증 시 필요한 공개키를 캐시해서 사용하고 있기 때문에 문제는 없다고 판단했다.

4. 결정타: /health도 느렸다

원인을 찾다가 /health api를 확인해봤다. 이 api는 인증도 DB조회도 하지 않는 api인데 이 api마저 500ms정도 걸렸다. 그렇다는건 원인이 더 앞단에 있지 않을까 라는 의심으로 이어졌다.

5. origin은 결백했다

이 서비스가 배포된 GCP VM에서 SSH로 접속해서 curl로 /health를 직접 호출해봤다. 이렇게 하면 Cloudflare를 거치지 않고 nginx + node로 바로 가는것인데, 응답은 25ms 였다. 브라우저에서 잰 500ms 와는 20배 넘게 차이가 났다.

같은 API를 쟀는데 이렇게 차이가 난다는 건, 브라우저 쪽 경로에만 뭔가 끼어 있다는 뜻이다. 우리 서비스는 프론트와 API가 같은 도메인이고 경로(/web, /api)로만 나뉘어 있어서, API 요청도 프론트와 똑같이 Cloudflare를 거쳐 들어온다. 그래서 남은 용의자는 Cloudflare였다.

6. 남은 용의자: Cloudflare 엣지

브라우저와 origin 사이 정확히 어디서 시간이 새는지는 아직 모른다. 다만 아직 확인은 못 했다. Cloudflare Analytics를 보려면 계정 초대가 필요한데, 아직 받지 못했다. 초대를 받으면 이 구간을 마저 들여다볼 예정이다.