사이트가 왜 이렇게 느리지?— 지연의 원인 체크

사이트가 왜 이렇게 느리지? Vercel + Supabase 지연 해결기 | IMLAB Tech Blog
IMLAB Tech Blog 성능 개선 해결 완료 Vercel · Supabase

사이트가 왜 이렇게 느리지?
— Vercel + Supabase 지연의 진짜 원인

바이브코딩으로 만든 사이트, 배포했더니 페이지 로딩이 3~4초. 코드 문제가 아니었습니다. 서버가 지구 반 바퀴를 돌아다니고 있었거든요.

IMLAB.AI · 2026년 4월 · AI & 기술 · 개발 환경 · 예상 시간 7분
먼저 결론부터

Vercel + Supabase 조합에서 서버리스 함수의 실행 리전을 지정하지 않으면, 한국 사용자가 접속해도 요청이 미국(버지니아)을 거쳐 인도(뭄바이)까지 왕복하는 일이 벌어집니다.

DB 쿼리 한 번에 약 380ms. SSR 페이지에 쿼리가 5~10개면 최대 3~4초가 DB 대기시간에 쓰입니다. 함수 리전을 도쿄(hnd1)로, DB를 도쿄/서울로 맞추면 같은 쿼리가 약 35ms로 줄어듭니다. 설정 파일 몇 줄이 전부입니다.

❌ 개선 전 — 최악의 경우
한국 유저 → Vercel 엣지 (서울)Function (미국 DC) +200ms↑Supabase DB (뭄바이) +180ms↑
총 DB 왕복: 약 380ms / 쿼리
✅ 개선 후
한국 유저 → Vercel 엣지 (서울)Function (도쿄) +30msSupabase DB (도쿄/서울) +5ms
총 DB 왕복: 약 35ms / 쿼리 (약 10배 이상 개선)

처음엔 코드 문제인 줄 알았습니다

Vercel에 Next.js 프로젝트를 배포했습니다. 로컬에서는 빠른데, 배포하고 나서 SSR 페이지를 열 때마다 화면이 뜨기까지 3~4초가 걸렸습니다. 처음엔 당연히 코드 문제라고 생각했습니다.

1
이미지 최적화를 했습니다
이미지 사이즈를 줄이고 lazy loading을 적용했습니다. 효과가 없었습니다.
2
쿼리 수를 줄여봤습니다
10개 쿼리를 5개로 줄였더니 절반 정도 빨라졌습니다. 그런데 여전히 느렸습니다. 쿼리 하나에 300ms 이상이 걸리고 있다는 걸 그때야 발견했습니다.
3
Vercel 함수 로그를 확인했습니다
Vercel 대시보드의 Functions 탭에서 로그를 보니, 함수 실행 리전이 iad1 (미국 버지니아)로 표시되고 있었습니다. 한국 사용자가 접속하는데 함수가 미국에서 실행되고 있었던 것입니다.
잠깐, 이론 설명
Vercel의 엣지 네트워크 vs 서버리스 함수는 다릅니다

Vercel을 사용하면 정적 파일(HTML, CSS, 이미지)은 전 세계 엣지 네트워크로 자동 배포됩니다. 서울 사용자가 접속하면 서울 엣지 서버에서 파일을 받아 빠릅니다.

그런데 서버리스 함수(API Routes, Server Actions, SSR)는 다릅니다. 함수는 특정 리전에 배포됩니다. 리전을 지정하지 않으면 Vercel은 기본값인 미국 버지니아(iad1)를 사용합니다. 서울 유저가 클릭해도 요청이 미국까지 날아가서 처리하고 돌아오는 것입니다.


왜 뭄바이가 문제였을까요

함수가 미국에 있는 것도 문제였지만, 더 큰 문제는 DB가 인도 뭄바이에 있었다는 점입니다.

FM대로 Supabase 프로젝트를 처음 만들게 되면 리전을 선택하는 화면이 나옵니다. 하지만 MCP로 연결로 승인처리 하면서 문제가 발생했었던 것이였습니다. Supabase의 기본 리전이 인도 뭄바이(ap-south-1)였던 것입니다.

잠깐, 이론 설명
물리적 거리가 곧 지연(Latency)입니다

인터넷 데이터는 광속으로 이동하지만, 지구는 큽니다. 미국 버지니아에서 인도 뭄바이까지 직선 거리는 약 13,000km입니다. 빛의 속도를 감안해도 왕복에만 이론적으로 80~100ms가 걸립니다. 실제로는 라우팅, 처리 시간 등이 더해져 180ms 이상이 됩니다.

SSR 페이지 하나를 렌더링하기 위해 DB 쿼리를 10번 실행한다면? 180ms × 10 = 1,800ms가 순수 DB 왕복에만 쓰입니다. 여기에 함수 실행 시간, 네트워크 오버헤드를 더하면 3~4초가 나오는 것입니다.

코드가 아무리 최적화돼 있어도, 요청이 지구를 반 바퀴 돌고 있다면 빠를 수가 없습니다.


해결 방법 — 리전을 같은 곳으로 맞춰주면 됩니다

해결책은 생각보다 단순했습니다. 함수 실행 리전과 DB 리전을 가능한 가깝게 맞추는 것입니다. 한국 사용자를 위한 서비스라면 일본 도쿄(Vercel hnd1) 또는 한국 서울(Supabase ap-northeast-2) 조합이 현실적인 최선입니다.

주의 — Supabase 리전은 프로젝트 생성 후 변경 불가

Supabase DB 리전은 프로젝트를 처음 만들 때만 선택할 수 있습니다. 이미 뭄바이로 만들었다면 새 프로젝트를 만들고 데이터를 마이그레이션해야 합니다. 처음 시작할 때 리전 선택이 얼마나 중요한지 알 수 있는 부분입니다.

1단계 — Supabase DB 리전 설정 (신규 프로젝트 기준)

Supabase에서 새 프로젝트를 생성할 때 리전 선택 화면에서 한국 서비스라면 아래 두 곳 중 하나를 선택합니다.

리전 이름 위치 특징
ap-northeast-1 일본 도쿄 한국과 약 5~10ms, 가장 일반적인 선택
ap-northeast-2 한국 서울 (베타) 가장 가깝지만 가용성 확인 필요

2단계 — Vercel 함수 리전 설정

프로젝트 루트에 vercel.json 파일을 만들거나, 이미 있다면 아래 설정을 추가합니다.

변경 전 (기본값 — 지정 안 함 = 미국)
// vercel.json 없거나 regions 설정 없음
// → 함수가 iad1 (미국 버지니아)에서 실행됨
변경 후 — vercel.json
{
  "functions": {
    "app/**/*.ts": {
      "regions": ["hnd1"]  // 도쿄
    }
  }
}

Next.js App Router를 사용하고 있다면, 특정 라우트의 런타임 설정으로도 지정할 수 있습니다.

app/page.tsx 또는 route.ts — 라우트별 지정
// 해당 파일에 추가
export const preferredRegion = 'hnd1'  // 도쿄

// 또는 배열로 여러 리전 지정 (가장 가까운 곳 자동 선택)
export const preferredRegion = ['hnd1', 'icn1']

3단계 — 배포 후 확인

설정을 적용하고 배포한 뒤, Vercel 대시보드 → Functions 탭에서 실행 리전이 바뀌었는지 확인합니다. 브라우저 개발자 도구(F12) → Network 탭에서 API 응답 시간도 비교해 보면 효과를 직접 확인할 수 있습니다.

터미널 — curl로 응답 시간 측정
# 개선 전후 응답 시간 비교
curl -o /dev/null -s -w "\nTotal: %{time_total}s\n" \
  https://your-site.vercel.app/api/your-endpoint

실제로 어떻게 달라졌나요

리전을 맞추고 나서 수치가 확실하게 달라졌습니다.

측정 항목 개선 전 개선 후
DB 쿼리 1회 왕복 약 380ms 약 35ms (약 10배 개선)
함수 실행 리전 iad1 미국 버지니아 hnd1 일본 도쿄
DB 리전 ap-south-1 인도 뭄바이 ap-northeast-1 일본 도쿄
SSR 페이지 로드 (쿼리 5개) 약 2~3초 약 300~500ms

페이지가 열리기를 기다리던 3~4초가, 눈 깜짝할 사이에 뜨는 수준이 됐습니다. 코드를 한 줄도 건드리지 않고, 리전 설정 파일 몇 줄만 추가했을 뿐입니다.


처음부터 제대로 설정하기 — 체크리스트

바이브코딩이나 새 프로젝트를 시작할 때 아래 항목을 확인해 두면 나중에 같은 고생을 하지 않아도 됩니다.

  • Supabase 프로젝트 생성 시 리전을 먼저 확인합니다. 한국 서비스라면 도쿄(ap-northeast-1) 또는 서울(ap-northeast-2)을 선택합니다. 기본값 그대로 넘어가지 않습니다.
  • Vercel 배포 후 Functions 탭에서 실행 리전을 확인합니다. iad1이 보이면 vercel.json에 리전을 명시적으로 지정합니다.
  • 함수 리전과 DB 리전을 같은 곳 또는 최대한 가깝게 맞춥니다. 리전이 다르면 DB 쿼리마다 불필요한 지연이 쌓입니다.
  • SSR 페이지의 DB 쿼리 수를 파악해 둡니다. 쿼리가 많을수록 지연이 선형으로 늘어납니다. N+1 쿼리 문제가 없는지도 함께 확인합니다.
  • 자주 바뀌지 않는 데이터는 캐싱을 고려합니다. 리전을 맞추는 것 다음으로 효과가 큰 최적화입니다. Next.js의 revalidate나 Vercel KV를 활용하면 DB를 아예 안 거칠 수 있습니다.
조금 더 알고 싶다면
왜 Vercel은 기본값이 미국일까요?

Vercel 자체가 미국 회사이고, 가장 많은 사용자가 미국·유럽에 있습니다. 기본값은 항상 가장 많은 사람에게 최적화된 설정입니다. 한국처럼 특정 지역 서비스를 만들 때는 개발자가 직접 지역에 맞게 설정을 바꿔줘야 합니다. 이건 Vercel의 잘못이 아니라, 글로벌 플랫폼의 기본 특성입니다.

AI 도구로 코드를 생성할 때도 마찬가지입니다. AI는 리전 설정까지 자동으로 최적화해주지 않습니다. 인프라 설정은 개발자가 직접 챙겨야 하는 영역입니다.


자주 묻는 질문

Q이미 Supabase를 뭄바이로 만들었습니다. 어떻게 하나요?
Supabase 리전은 프로젝트 생성 후 변경이 불가능합니다. 새 프로젝트를 도쿄 리전으로 만든 뒤, Supabase CLI로 기존 데이터를 마이그레이션해야 합니다. supabase db dump로 스키마와 데이터를 내보내고 새 프로젝트에 적용하면 됩니다. 번거롭지만 초기에 설정을 제대로 잡는 것이 나중에 훨씬 편합니다.
Q리전을 도쿄로 바꾸면 다른 나라 사용자에게 더 느려지지 않나요?
정적 파일(이미지, HTML, CSS)은 Vercel 엣지 네트워크가 전 세계에 자동 배포하므로 영향을 받지 않습니다. DB 쿼리가 포함된 SSR 페이지나 API는 도쿄 함수를 거치게 됩니다. 주요 사용자가 한국·일본이라면 도쿄가 최선입니다. 미국·유럽 사용자도 중요하다면 리전을 여러 개 지정하거나 엣지 런타임 사용을 검토할 수 있습니다.
Q리전 설정 외에 추가로 할 수 있는 최적화가 있나요?
있습니다. 리전 정렬 다음으로 효과가 큰 것은 캐싱입니다. 자주 바뀌지 않는 데이터는 Vercel KV나 Next.js의 unstable_cache로 캐싱하면 DB 쿼리 자체를 없앨 수 있습니다. 그 외에 N+1 쿼리 문제 해결, Supabase의 Connection Pooling 활성화, 인덱스 추가 등도 효과적입니다.

핵심 요약표

항목 문제 상황 해결 방법 효과
함수 리전 기본값 미국 버지니아(iad1) vercel.json에 hnd1(도쿄) 명시 한국↔함수 지연 대폭 감소
DB 리전 Supabase 기본값 인도 뭄바이 신규 프로젝트를 도쿄/서울로 생성 함수↔DB 지연 180ms → 5ms
DB 쿼리 수 SSR 페이지에 5~10개 쿼리 리전 정렬 + 쿼리 수 최소화 페이지 로드 3~4초 → 수백ms
캐싱 매 요청마다 DB 조회 Vercel KV 또는 revalidate 적용 DB 쿼리 자체를 제거
참고
Vercel 공식 문서 — Regions & Edge Network · Supabase 공식 문서 — Project Regions · Next.js 공식 문서 — preferredRegion · IMLAB 자체 경험 기록