Vercel 함수를 도쿄 리전에 고정해 체감 속도를 개선한 이야기 — 태평양 왕복 문제 해결

HeatMapX Engineering Team5 min read
  • engineering
  • nextjs
  • performance
  • vercel

이 글의 요약

  • 대시보드가 느렸던 원인은 "Vercel 함수는 미국, DB는 도쿄"라서 매번 태평양을 왕복하고 있었기 때문
  • x-vercel-id 응답 헤더로 어느 리전에서 실행되었는지 확인할 수 있음
  • vercel.jsonregions로 도쿄에 고정 + 쿼리 병렬화를 적용해, 사내 측정 기준 몇 초 → 약 0.2초로 단축

"대시보드 화면 전환에 몇 초씩 걸린다" — 이 체감 지연을 조사하고, 원인을 특정해 개선한 기록입니다. 추측이 아니라 실측으로 원인을 하나씩 분리해 나갔습니다.

증상과 원인 분리

화면 전환에 약 3초가 걸렸습니다. 먼저 "서버의 초기 응답(TTFB)"과 "내용 로딩" 중 어느 쪽이 느린지 분리해 본 결과, 초기 응답은 빠르고 페이지 내 데이터 로딩이 느리다는 것을 알게 되었습니다.

각 쿼리 자체는 데이터베이스 상에서는 수 밀리초로 빨랐습니다. 그럼에도 전체는 느렸습니다. 여기서 의심한 것이 **실행 위치(리전)**였습니다.

원인 ①: 태평양을 왕복하고 있었다

응답 헤더 x-vercel-id를 확인해 보니, 함수가 **미국 동부 리전(iad1)**에서 실행되고 있었습니다. 반면 데이터베이스(Supabase)는 도쿄에 있었습니다. 즉 쿼리를 실행할 때마다 일본↔미국 간 왕복이 발생하고 있었던 것입니다.

헤더는 다음과 같이 보입니다(예시).

x-vercel-id: hnd1::iad1   ← 접수는 도쿄(hnd1)지만, 실행은 미국(iad1)

쿼리가 여러 번 발생하면 그때마다 태평양을 왕복하며 지연 시간이 누적됩니다.

원인 ②: 쿼리를 직렬로 기다리고 있었다

또 하나, 홈 화면이 여러 집계 데이터를 **직렬(하나씩 순서대로)**로 가져오고 있었습니다. 왕복 지연이 그대로 횟수만큼 쌓이는 구조였습니다.

대응

리전을 도쿄로 고정

vercel.json에 리전 지정을 추가해, 함수가 도쿄(hnd1)에서 실행되도록 했습니다.

{ "regions": ["hnd1"] }

이렇게 하면 x-vercel-idhnd1::hnd1이 되어, 함수와 DB가 모두 도쿄에 위치하게 됩니다. 이를 통해 왕복 지연이 해소되었습니다.

쿼리 병렬화

직렬로 대기하던 집계 데이터 로딩을 Promise.all로 병렬화하고, 중복되어 있던 데이터 로딩도 하나로 통합했습니다.

결과

사내 측정 결과, 홈 화면 표시 시간이 몇 초에서 약 0.2초로 단축되었습니다. 핵심은 캐시에 의존하지 않고 처리 자체를 빠르게 만들었다는 점입니다. 표시되는 데이터는 항상 최신 상태 그대로 유지됩니다.

배운 점

  • "쿼리는 빠른데 화면은 느리다"면, DB 속도만이 아니라 **함수와 DB의 물리적 거리(리전)**를 의심해 볼 것.
  • x-vercel-id는 실행 리전을 확인할 수 있는 간단하면서도 강력한 단서.
  • 왕복 비용이 큰 환경에서는 직렬 대기가 치명적이다. 병렬화의 효과가 크다.

정리

체감 지연의 정체는 미국과 도쿄 간의 왕복이었습니다. 리전 고정과 병렬화라는 두 가지 대응으로, 캐시 없이도 체감 속도를 크게 개선할 수 있었습니다. SSR이나 대시보드가 느리다고 느껴진다면, 먼저 실행 리전과 DB의 위치 관계를 확인해 보시기 바랍니다.

Claude Code에서 실행하는 히트맵, 무료로 시작.

한 줄의 트래커 태그를 붙이고 CLI에서 분석부터 개선 제안까지.