Supabase가 자꾸 502를 내거나 느려질 때 먼저 확인할 5가지 원인을 정리합니다. 무료 플랜 제한부터 커넥션 풀, 인덱스, 리전, 로그 확인까지 순서대로 짚어봅니다.

Supabase에서 502 Bad Gateway나 느린 응답이 반복된다면, 일부 환경에서는은 서비스 장애가 아니라 커넥션 풀·쿼리·리전 설정 중 하나가 원인입니다. 이 글은 원인을 빈도순으로 정리하고, 대시보드에서 직접 확인할 수 있는 지점을 순서대로 안내합니다. 처음엔 코드부터 뜯어보기 쉽지만, 진짜 원인은 프로젝트 설정 한 줄이나 인덱스 하나에 숨어 있을 때가 많습니다.
Supabase는 오픈소스 백엔드 서비스로, PostgreSQL 데이터베이스에 인증·스토리지·실시간 기능을 얹은 플랫폼입니다. 편한 만큼 병목이 여러 층에 걸쳐 있어서, 어디서 막히는지 감을 잡는 게 중요합니다.
💡 아래 체크 순서는 "일부 환경에서는 원인부터"로 정렬했습니다. 위에서부터 하나씩 확인하면 일부 환경에서는의 502·지연은 해결됩니다.
502가 뜨는 진짜 이유부터 짚기
502 Bad Gateway는 "중간 게이트웨이가 뒷단 서버로부터 정상 응답을 못 받았다"는 뜻입니다. Supabase에서는 주로 다음 상황에서 발생합니다.
- 데이터베이스가 커넥션(연결 슬롯)을 다 써서 새 요청을 못 받을 때
- 쿼리가 너무 오래 걸려 게이트웨이 타임아웃을 넘길 때
- 프로젝트가 무료 플랜에서 일시 정지(pause) 상태로 들어갔을 때
- 리전(서버 위치)이 사용자와 멀어 왕복 시간이 누적될 때
| 증상 | 가장 유력한 원인 |
|---|---|
| 특정 시간대만 502 급증 | 커넥션 풀 고갈, 트래픽 스파이크 |
| 환경에 따라 느림 (2~10초) | 인덱스 누락, N+1 쿼리 |
| 며칠 쉬었더니 첫 요청만 실패 | 무료 플랜 자동 pause |
| 국내 사용자만 느림 | 리전이 미국·유럽에 있음 |
| 갑자기 전체 다운 | Supabase 상태 페이지 확인 필요 |
먼저 status.supabase.com에서 플랫폼 장애 여부를 확인하고, 이상이 없다면 아래 5가지를 순서대로 봅니다.
1. 커넥션 풀이 터졌는지 확인
Supabase 502의 1순위 원인은 커넥션 고갈입니다. PostgreSQL은 동시에 열 수 있는 연결 수에 제한이 있고, 무료·저가 플랜일수록 이 한도가 작습니다.
커넥션(connection)이란 앱과 DB 사이에 열어둔 통신 회선입니다. 회선 수가 정해진 콜센터를 떠올리면 됩니다. 모든 회선이 통화 중이면 다음 손님은 연결음만 듣다가 끊기죠. 502가 바로 그 신호입니다.
확인 방법:
- Supabase 대시보드 → 프로젝트 선택
- 왼쪽 메뉴 Database → Roles 또는 Reports에서 현재 연결 수 확인
- 상한선에 근접하거나 자주 초과하면 원인 확정
해결 순서:
- Connection Pooler(연결 풀러) 사용: Supabase는 PgBouncer 기반 풀러를 기본 제공합니다. 앱 코드가 DB에 직접 붙는 URL 대신 Pooler URL을 쓰면, 실제 연결 하나를 여러 요청이 나눠 씁니다.
- 서버리스 환경이면 반드시 Pooler: Vercel·Netlify·AWS Lambda처럼 함수가 매번 새로 뜨는 환경은 커넥션을 순식간에 소모합니다. 이 경우 Pooler URL의 transaction mode가 표준 권장입니다.
- 커넥션을 안 닫는 코드 점검:
client.end()또는pool.release()를 빼먹은 자리가 있으면 좀비 연결이 쌓입니다.
[앱 서버] ──┐
[앱 서버] ──┼─→ Pooler ─→ Postgres
[앱 서버] ──┘ (연결 재사용)
Pooler를 거치면 위 그림처럼 실제 DB 연결 하나를 여러 앱 요청이 돌려쓰게 됩니다.
2. 무료 플랜 pause 상태인지 체크
Supabase 무료 플랜 프로젝트는 일정 기간 활동이 없으면 자동으로 일시 정지됩니다. 이 상태에서 접속하면 첫 요청이 502나 타임아웃으로 뜨는 경우가 많습니다.
주말 지나고 월요일에 접속했을 때, 또는 사이드 프로젝트를 오랜만에 열었을 때 유독 502가 잘 뜬다면 이 케이스입니다.
확인 방법:
- 대시보드 접속 시 프로젝트 카드에 "Paused" 배지가 보이면 정지 상태
- 이 경우 Restore 버튼으로 다시 깨워야 합니다
pause 정책의 정확한 기간·조건은 요금제 페이지가 종종 업데이트되므로, Supabase 공식 요금제 문서에서 현재 기준을 확인하는 것이 안전합니다. 프로덕션 서비스라면 유료 플랜으로 올려 pause 자체를 없애는 편이 낫습니다.
3. 느린 쿼리와 인덱스 누락 잡기
응답이 환경에 따라 2~10초씩 걸린다면 코드가 아니라 쿼리가 범인일 확률이 높습니다. Supabase 대시보드에는 느린 쿼리를 잡아주는 도구가 내장돼 있습니다.
확인 경로:
- Database → Query Performance: 가장 오래 걸린 쿼리 목록
- Database → Indexes: 현재 걸린 인덱스 확인
- SQL Editor에서
EXPLAIN ANALYZE 쿼리문실행 → 실제 실행 계획 확인
인덱스(index)는 책의 색인과 같습니다. 색인이 없으면 원하는 단어를 찾으려고 책을 처음부터 끝까지 넘겨야 하죠. DB도 마찬가지로, 인덱스가 없는 컬럼으로 검색하면 테이블 전체를 훑습니다. 데이터가 만 건만 넘어가도 체감 속도가 확 떨어집니다.
흔한 개선 지점:
| 상황 | 처방 |
|---|---|
WHERE user_id = ? 자주 쓰는데 느림 |
user_id 컬럼에 인덱스 추가 |
| 리스트 화면이 갈수록 느려짐 | SELECT * 대신 필요한 컬럼만 |
| 관련 데이터 여러 개 불러올 때 느림 | N+1 → 조인 또는 .select(', related()') |
| 정렬이 느림 | ORDER BY 컬럼에 인덱스 추가 |
예를 들어 블로그 글 목록 화면에서 "글 100개를 불러오고, 각 글마다 작성자 정보를 따로 또 100번 요청"하는 구조라면, 이게 전형적인 N+1 문제입니다. Supabase 클라이언트에서 select(', author()') 형태로 한 번에 가져오도록 바꾸면 요청 수가 극적으로 줄어듭니다.
4. 리전 위치와 네트워크 지연
서버가 지구 반대편에 있으면 코드가 아무리 최적화돼도 왕복 시간이 붙습니다. 한국 사용자를 대상으로 하는 서비스인데 프로젝트 리전이 미국 동부(us-east-1)라면, 요청 하나당 수백 밀리초의 네트워크 지연이 기본으로 깔립니다.
확인 방법:
- 대시보드 → Project Settings → General에서 현재 리전 확인
- 한국 서비스라면 ap-northeast-1(도쿄) 또는 ap-northeast-2(서울) 리전이 유리
주의: Supabase는 프로젝트 생성 후 리전 변경이 자유롭지 않습니다. 마이그레이션이 필요한 경우가 일부 환경에서는이므로, 새 프로젝트를 만들어 데이터를 옮기는 방향을 검토해야 합니다. 초기 세팅 단계라면 지금 리전부터 확인해 두는 게 훨씬 편합니다.
리전 외에도 CDN·엣지 함수를 앞에 두면 이미지·정적 자원의 지연은 크게 줄어듭니다. 다만 DB 왕복 자체는 리전으로 결정되니, 여기가 가장 먼저입니다.
5. 로그와 모니터링에서 진짜 신호 찾기
추측 대신 로그를 봐야 진짜 원인이 나옵니다. Supabase 대시보드의 로그 도구는 계층별로 나뉘어 있어, 어디서 문제가 터졌는지 좁혀줍니다.
- Logs → API: HTTP 요청·응답, 502가 실제로 어느 엔드포인트에서 났는지
- Logs → Postgres: DB 에러, 락(lock) 대기, 커넥션 관련 메시지
- Logs → Auth: 로그인·토큰 관련 이슈
- Reports: 시간대별 요청량·에러율 그래프
체크리스트로 정리하면 이렇습니다.
- ☐status.supabase.com에서 플랫폼 장애 여부 확인
- ☐프로젝트가 pause 상태는 아닌지 확인
- ☐Reports에서 커넥션 사용량 그래프 확인
- ☐앱이 Pooler URL을 쓰는지 코드에서 확인
- ☐Query Performance에서 상위 5개 느린 쿼리 확인
- ☐자주 쓰는 WHERE·ORDER BY 컬럼에 인덱스 있는지
- ☐프로젝트 리전이 사용자와 가까운지
- ☐API 로그에서 502가 특정 시간·엔드포인트에 몰리는지
특히 "특정 시간대만 502"라면 트래픽 스파이크와 커넥션 고갈 조합일 가능성이 크고, "특정 엔드포인트만 느림"이면 그 쿼리 하나가 범인일 확률이 높습니다.
참고: 지금 쓰는 Supabase 버전 확인
셀프호스팅으로 Supabase를 직접 운영 중이라면, 버전이 오래됐을 때 성능 이슈가 상위 버전에서 이미 수정된 경우가 있습니다. 공식 저장소 기준 최신 릴리스는 v1.26.07 (2026-07-09 릴리스) 입니다(글 작성 시점 기준, github.com/supabase/supabase). 매니지드 클라우드를 쓴다면 Supabase 측에서 자동으로 관리되므로 이 항목은 넘어가도 됩니다.
막히면 여기부터 다시 본다
502와 느린 응답은 일부 환경에서는 커넥션 풀 → pause 상태 → 느린 쿼리 → 리전 → 로그 순으로 확인하면 원인이 드러납니다. 이 다섯 지점을 순서대로 훑는 습관만 있어도, 무작정 재배포하거나 코드를 갈아엎는 시간을 크게 줄일 수 있습니다.
다음에 502가 뜨면 가장 먼저 대시보드의 Reports와 Logs → API 두 화면을 열어보세요. 여기서 이상 신호가 잡히면 원인 후보가 절반으로 줄어듭니다. 그래도 좁혀지지 않으면 Supabase 공식 디스코드나 GitHub Discussions에 로그 스크린샷과 함께 질문하는 편이 훨씬 빠릅니다.
함께 보면 좋은 글
- Supabase 무료 요금제 한계, 어디까지 무료로 쓸 수 있을까
- Supabase 5분 입문 — 코드 적게 쓰는 백엔드의 정답일까
- Chroma 실전 예제 — 내 문서 검색 챗봇 30분 만들기
조치 후 정상 동작 확인
앞선 다섯 단계 중 하나라도 설정을 바꿨다면, 다음 항목으로 회복 여부를 확인합니다.
- 대시보드 Reports 재확인: 조치 직후 5~10분 동안 에러율 그래프가 이전 대비 떨어지는지 관찰합니다.
- Logs → API에서 502 재현 여부: 문제로 지목된 엔드포인트를 다시 호출해 상태 코드가 200 계열로 돌아왔는지 확인합니다.
- 커넥션 사용량 그래프: Pooler URL로 전환한 경우, 활성 연결 수가 상한선 아래로 안정화됐는지 봅니다.
- Query Performance 재측정: 인덱스를 추가했다면 대상 쿼리의 평균 실행 시간이 눈에 띄게 줄었는지 다시 조회합니다.
- 체감 응답 시간: 실제 서비스 화면에서 대표 시나리오(로그인, 목록 조회 등)를 눌러 지연이 사라졌는지 최종 확인합니다.
한 지표만 보고 판단하지 말고, Reports·Logs·실사용 세 곳에서 같은 방향으로 개선 신호가 잡힐 때 "해결됨"으로 마무리하는 편이 안전합니다.
조치가 오히려 상태를 악화시켰다면 되돌리기
설정을 바꿨는데 502가 더 잦아지거나 새로운 에러가 튀어나올 수 있습니다. 이때는 원상복구 절차를 준비해 두는 편이 낫습니다.
- 연결 문자열 롤백: Pooler URL로 바꾼 뒤 앱에서 트랜잭션·prepared statement 관련 오류가 난다면, 환경변수에 보관해 둔 이전 직접 연결 URL로 되돌립니다. 배포 플랫폼에서 이전 배포로 즉시 롤백할 수 있게 설정 변경과 코드 배포는 분리해 두는 것이 좋습니다.
- 인덱스 되돌리기: 새로 만든 인덱스가 쓰기 성능을 떨어뜨렸다면
DROP INDEX 인덱스명;으로 제거합니다. 인덱스 생성 시 이름을 지정해 두면 롤백이 쉽습니다. - 쿼리 변경 취소:
select(', author()')형태로 조인을 늘렸는데 응답 크기가 커져 오히려 느려졌다면, 이전 쿼리로 되돌리고 필요한 컬럼만 지정하는 방식으로 다시 접근합니다. - 프로젝트 리전 이전 중단: 새 리전으로 마이그레이션을 시도하다 데이터 정합성 문제가 보이면, 트래픽 전환 전 단계에서 기존 프로젝트로 DNS·환경변수를 되돌립니다. 이전 프로젝트를 곧바로 삭제하지 말고 최소 며칠은 유지해 두는 편이 안전합니다.
- 롤백 후 재확인: 되돌린 다음에도 위 "조치 후 정상 동작 확인" 항목을 다시 돌려, 최소한 원래 상태로는 회복됐는지 검증합니다.
변경 전 상태로 언제든 돌아갈 수 있도록, 설정을 바꾸기 전에 이전 값(연결 URL, 쿼리문, 인덱스 정의)을 별도로 기록해 두는 습관을 권장합니다.
'개발 & 기술 > 데이터베이스' 카테고리의 다른 글
| SQL 결과 엑셀 내보내기, 방법 3가지와 한글 깨짐 해결 (0) | 2026.08.09 |
|---|---|
| SQL JOIN 정리: INNER·LEFT·OUTER를 그림으로 이해하기 (0) | 2026.07.26 |
| Chroma vs Pinecone 비교: 벡터 DB 선택 기준 정리 (0) | 2026.07.23 |
| SQL WHERE와 GROUP BY 정리: 비개발자가 자주 막히는 문법 (0) | 2026.07.22 |
| Supabase 무료 요금제 한계, 어디까지 무료로 쓸 수 있을까 (0) | 2026.07.13 |