본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 06. 05. 00:36

Supabase를 Mumbai에서 Tokyo로 이전하여 DB 레이턴시를 1/3로 줄인 이야기 (삽질 포인트 전부 공개)

요약

Supabase 프로젝트의 리전을 Mumbai에서 Tokyo로 이전하여 DB 레이턴시를 1/3로 단축한 경험담입니다. 리전 변경이 불가능하여 새 프로젝트를 생성해야 하는 과정과 환경 변수 설정 및 신규 API 키 형식 적용 시 주의할 점을 다룹니다.

핵심 포인트

  • Supabase는 기존 프로젝트의 리전 변경이 불가능하여 새 프로젝트 생성이 필요함
  • 리전 이전을 통해 DB 레이턴시를 약 1/3 수준으로 대폭 개선 가능
  • 환경 변수 설정 시 대시보드 URL이 아닌 실제 Project URL을 사용해야 함
  • 신규 프로젝트는 변경된 API 키 형식(sb_publishable_/sb_secret_)을 권장함

서론

개인 개발 중인 일본 주식 분석 서비스 「주식 AI 분석」을 운영하고 있는 21세 대학생입니다.

서비스 공개 후 프로파일링을 해보니, **Supabase의 리전(Region)이 Mumbai (인도)**로 설정되어 있다는 것을 깨달았습니다.

일본 사용자 대상 서비스인데, API → DB 왕복 과정에서 매번 130-150ms가 추가로 소요되는 상태였습니다.

Tokyo 리전으로 이전했더니 DB 레이턴시(Latency)가 약 1/3로 개선되었습니다. 본 기사에서는 그 이전 절차와, 은근히 여러 번 막혔던 삽질 포인트(ハマりポイント)를 전부 공개합니다.

이전 계기

어느 날 Supabase 대시보드에서 자신의 프로젝트 리전을 확인해보니:

Region: ap-south-1 (Mumbai)

언제 선택했는지 기억이 나지 않습니다 (프로젝트 생성 시 기본값으로 선택되었거나, 아무거나 눌렀던 것 같습니다).

일본 사용자로부터 API 요청 → Render origin (미국 또는 싱가포르) → Supabase Mumbai → DB → ... 와 같이, 지구를 반 바퀴 돌고 있는 상태였습니다.

레이턴시 참고치:

경로RTT
일본 ↔ Tokyo5-10ms
...

포트폴리오 화면 등 여러 쿼리를 호출하는 화면에서 체감되는 느림. 사용자가 0명인 지금이 최적의 타이밍이기에 즉시 이전을 결정했습니다.

이전 절차 (개요)

Supabase는 기존 프로젝트의 리전 변경이 불가능하므로, 새 프로젝트를 만들어 수동으로 전환해야 합니다.

1. Tokyo 리전에서 새 프로젝트 생성
2. 스키마 (schema.sql) 적용
3. RLS 정책 적용
...

사용자가 0명이었기 때문에 데이터 이전은 스킵하고 빈 DB로 전환하기만 하면 되었습니다. 이 점이 편리했습니다.

삽질 포인트 전부 공개

1. NEXT_PUBLIC_SUPABASE_URL에 대시보드 URL을 붙여넣는 실수

  1. Supabase 새 프로젝트 생성 후, API 키 화면을 연 브라우저의 URL이 다음과 같습니다:
https://supabase.com/dashboard/project/fpxwajrdiwsvyyhcoook/settings/api

이것을 Project URL이라고 생각하고 Render의 env(환경 변수)에 붙여넣었습니다. 당연히 API 호출이 모두 실패했습니다.

정답은 이것입니다:

https://fpxwajrdiwsvyyhcoook.supabase.co

대시보드 URL에서 프로젝트 ref (fpxwajrdiwsvyyhcoook)를 추출하여 .supabase.co를 붙이거나, Project Settings → API → Project URL의 값을 복사해야 합니다.

이는 개인 개발자라면 한 번쯤 겪을 수 있는 함정이니 주의하십시오.

2. API 키가 신규 형식 (sb_publishable_/sb_secret_)으로 변경됨

신규 프로젝트의 「Project Settings → API Keys」를 열면, 두 개의 탭이 있습니다:

  • Publishable and secret API keys ← 신규 형식 (기본값)
  • Legacy anon, service_role API keys ← JWT 형식 (구형)

처음에는 구 프로젝트와 마찬가지로 JWT 형식 (eyJ...)을 사용하려고 Legacy 탭에서 복사했더니, 설정이 미묘하게 어긋나 「Invalid API key」 에러가 연발되었습니다.

신규 프로젝트는 신규 형식을 사용하는 것이 무난합니다:

NEXT_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_JdYJJ...
SUPABASE_SERVICE_ROLE_KEY=sb_secret_8CxSv...

둘 다 📋 버튼으로 복사하십시오. 수동으로 선택하면 줄바꿈이나 공백이 포함될 원인이 됩니다.

JWT 키가 올바른지 진단하는 원라이너 (One-liner)

브라우저 Console에서:

JSON.parse(atob("PASTE_KEY_HERE".split('.')[1]))

{ ref: "<project-ref>", role: "service_role", ... }

와 같은 내용이 나옵니다.

  • ref가 프로젝트와 일치하는지
  • roleservice_role인지 anon인지

를 확인할 수 있습니다.

3. 「Automatically expose new tables」를 OFF로 설정하면 발생하는 permission denied 지옥

새 프로젝트 생성 시, 보안 설정에서:

항목권장
Enable Data APION
Automatically expose new tablesOFF
Enable automatic RLSON

「Automatically expose new tables」를 OFF로 설정하면 확실히 안전하지만, 신규 테이블에 대한 GRANT가 자동으로 부여되지 않는다.

그대로 INSERT INTO watchlist ...를 실행하면:

DB error: {
code: '42501',
message: 'permission denied for table watchlist',
...

정공법을 통한 해결 SQL:

-- service_role (백엔드 API 역할) に 전권한 부여
GRANT ALL ON ALL TABLES IN SCHEMA public TO service_role;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO service_role;
...

RLS (Row Level Security)가 모든 테이블에 활성화되어 있으므로, authenticated/anon에 GRANT를 넓게 설정하더라도 행 레벨(row level)에서 차단되기 때문에 안전하다.

권한 확인 SQL

SELECT grantee, privilege_type
FROM information_schema.table_privileges
WHERE table_schema = 'public'
...

INSERT/SELECT/UPDATE/DELETE 4가지가 갖춰져 있으면 OK.

4. Confirm signup 템플릿이 OTP 코드를 내보내지 않는 문제

이전 프로젝트에서는 Magic Link 또는 OTP 템플릿을 수정하여 8자리 숫자 코드로 설정했었지만, 신규 계정의 첫 사인업(Sign up) 시에는 Confirm signup 템플릿이 사용된다.

이 부분을 수정하는 것을 잊었기 때문에, 첫 로그인 시 사용자에게 "링크를 클릭하세요"라는 메일이 발송되어 예상과 다른 동작을 했다.

→ Magic Link 템플릿과 Confirm signup 템플릿 모두에서 {{ .ConfirmationURL }}{{ .Token }}으로 교체해야 한다.

<!-- Confirm signup의 Body -->
<div style="...">
<h2 style="...">주식 AI 분석 사인업 확인</h2>
...

이렇게 하면 Apple Mail의 프리페치(prefetch) 문제도 회피할 수 있다 (링크가 없으므로 소비되지 않음).

이전 후의 효과

API이전 전 (Mumbai)이전 후 (Tokyo)개선
/api/watchlist (GET)380ms130ms3배 속도
/api/portfolio (GET)520ms200ms2.5배 속도
인증 (signInWithOtp)1.6s0.7s2배 속도
/api/trending (DB 캐시 Hit)600ms230ms2.5배 속도

체감도 확실히 다르다. "리스트 계열의 화면이 순식간에 뜨는" 느낌으로 바뀌었다.

특히 여러 쿼리를 호출하는 /portfolio/journal에서 효과가 크다.

요약

  • 리전(Region)은 초기 선택 시 주의할 것. 기본값에 맡기면 지구 반대편에 배치된다.
  • Supabase는 기존 프로젝트의 리전 변경이 불가능하다. 새 프로젝트를 만들어 이전해야 한다.
  • 사용자 0명인 지금이 최적의 타이밍이다 (데이터 이전 불필요).
  • 신규 형식 API 키 (sb_publishable_* / sb_secret_*)를 사용한다.
  • 「Automatically expose new tables」를 OFF로 설정한 경우 수동 GRANT가 필요하다.
  • Confirm signup 템플릿도 반드시 수정한다.

앞으로 Supabase로 개인 개발을 시작하려는 사람은, 처음에 Tokyo 리전을 선택하는 것만으로 이 글의 함정들을 모두 회피할 수 있다.

리전을 나중에 바꾸는 것은 번거로우므로 처음이 중요하다.

🔗 서비스: https://jp-stock-analyzer.onrender.com

🔗 X (진척 상황·매출·실패를 전부 공개): https://x.com/tomato112924

이 계정에서 개인 개발의 생생한 기록을 발신할 예정이니,

괜찮으시다면 팔로우해 주세요.

Discussion

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0