콘텐츠로 이동
Study NoteSupabase

1. 왜 Supabase인가

BaaS의 전통적 대가는 종속성이다. Supabase는 그 대가를 줄이는 방향으로 설계된 BaaS다

새 프로젝트를 시작할 때마다 거의 같은 목록을 다시 만든다.

  • DB 띄우기, 커넥션 풀 설정, 마이그레이션 도구 붙이기
  • 회원가입 · 로그인 · 비밀번호 재설정 · 이메일 인증 · 소셜 로그인
  • 세션과 토큰 관리, 리프레시 로직, 만료 처리
  • 파일 업로드, 썸네일 생성, 권한이 걸린 파일 서빙
  • 실시간 갱신이 필요하면 WebSocket 서버 한 벌 더
  • 그리고 이 모든 것의 배포 · 모니터링 · 백업

문제는 이게 다 제품의 차별점이 아니라는 것이다. 어느 서비스나 똑같이 필요하다. BaaS(Backend as a Service)는 이 목록을 통째로 제품으로 사 오는 접근이다.

직접 구축은 API 서버·Auth·스토리지·WebSocket을 각각 만들어야 하고, BaaS는 관리형 백엔드 하나로 끝난다

관리형 Postgres 한 대와, 그 위에서 돌아가는 Auth · REST API · Realtime · Storage · Edge Functions를 한 프로젝트로 묶어 파는 오픈소스 플랫폼.

“Firebase 대안”이라는 표현이 흔하지만, 실제 정체성은 Postgres 플랫폼이다. 각 기능은 Postgres 위에 얹힌 별도 오픈소스 서버들이고(2장에서 하나씩 본다), 그래서 SQL로 직접 만질 수 있고 pg_dump로 통째로 들고 나올 수 있다.

“그냥 Postgres다”가 왜 중요한가

섹션 제목: ““그냥 Postgres다”가 왜 중요한가”
  1. 배운 게 남는다 — Supabase를 배우는 시간의 대부분이 Postgres를 배우는 시간이다. 회사를 옮겨도, 플랫폼을 바꿔도 남는다
  2. 도구 생태계를 그대로 쓴다 — Prisma, Drizzle, DBeaver, pgAdmin, Metabase. Postgres에 붙는 건 전부 붙는다
  3. 데이터를 인질로 잡히지 않는다 — 표준 덤프를 뜰 수 있다. 이전 경로가 항상 열려 있다는 사실 자체가 협상력이다
  4. 관계형 모델의 힘을 포기하지 않는다 — JOIN, 트랜잭션, 외래 키, 제약 조건, 뷰, 함수, 트리거 전부 그대로다

취향 차이가 아니라 데이터 모델과 쿼리 능력의 차이다.

  • 컬렉션 / 문서 / 서브컬렉션
  • 스키마 없음 → 초반 속도가 빠르다
  • 관계는 문서 ID를 손으로 들고 다닌다
  • 비정규화가 사실상 강제된다 — 조회 패턴마다 데이터를 복제해 둔다

비정규화의 진짜 비용은 저장 공간이 아니라 정합성 유지 코드다. “프로필 이름을 바꾸면 그 사람이 쓴 모든 댓글의 작성자 이름도 바꿔야 한다”가 코드로 남는다.

쿼리 — 예상하지 못한 질문에 답하기

섹션 제목: “쿼리 — 예상하지 못한 질문에 답하기”

같은 요구사항: “지난 30일간 카테고리별 주문 합계, 상위 5개”.

Firestore에서는 집계 쿼리가 제한적이라 앱에서 전부 읽어와 계산하거나, Cloud Function으로 미리 집계 문서를 만들어 두고 갱신한다. 즉 질문이 생길 때마다 파이프라인을 하나 만든다.

-- Supabase에서는 그냥 질문한다
select category, sum(total) as revenue
from orders
where created_at > now() - interval '30 days'
group by category
order by revenue desc
limit 5;

관계형 DB의 가치는 미리 예상하지 못한 질문에 답할 수 있다는 것이다. 제품이 성숙할수록 이 차이가 크게 벌어진다.

Supabase의 구성 요소는 대부분 개별 오픈소스 프로젝트다 (Postgres, PostgREST, GoTrue, Realtime, Storage API, Supavisor…). docker compose로 셀프호스팅할 수 있고, 실제로 그렇게 운영하는 곳이 있다.

Supabase Cloud와 셀프호스팅은 pg_dump·마이그레이션 파일로 오갈 수 있고 스키마와 정책이 같다

현실적으로는 대부분 셀프호스팅하지 않는다. 중요한 건 할 수 있다는 사실이 의사결정의 위험도를 낮춰준다는 점이다. 특히 회사에서 도입 승인을 받을 때 그렇다.

SupabaseFirebase직접 구축
데이터 모델관계형 (Postgres)문서형자유
쿼리SQL 전체제한적자유
권한 모델RLS (DB 내부)Security Rules앱 코드
초기 속도빠름매우 빠름느림
오픈소스○✕○
셀프호스팅○✕○
실시간○◎직접
운영 부담낮음매우 낮음높음
학습 전이성높음 (Postgres)낮음높음
제품실체
Database관리형 Postgres. 전체 권한 제공
Auth이메일/소셜/OTP(One-Time Password, 일회용 코드)/SSO(Single Sign-On, 조직 계정 연동) 로그인, JWT 발급 (auth 스키마)
StorageS3 호환 객체 스토리지 + CDN (storage 스키마)
RealtimeWebSocket 브로드캐스트 / 프레즌스 / DB 변경 구독
Edge FunctionsDeno 기반 서버리스 함수
Vectorpgvector 기반 임베딩 검색
Cron / Queuespg_cron, pgmq 기반 스케줄·큐
Studio웹 대시보드 (테이블 편집, SQL 에디터, 로그)

개발 속도가 실제로 빨라지는 지점도 여기서 나온다. 테이블을 만들면 PostgREST가 스키마를 읽어 API를 즉시 생성하고, supabase gen types typescript가 그 스키마에서 TypeScript 타입을 뽑아낸다. 권한 로직은 REST로 오든 Realtime으로 오든 같은 RLS 정책 하나로 끝난다.

언제 쓰고 언제 쓰지 말아야 하나

섹션 제목: “언제 쓰고 언제 쓰지 말아야 하나”

쓰면 좋은 경우

관계형 데이터가 중심인 서비스 — 커뮤니티, SaaS, 대시보드, 커머스, 협업 도구.

팀에 전담 백엔드/인프라 인력이 없거나 적을 때.

인증·권한이 사용자 소유 데이터 중심일 때 (“내 것만 보인다” 류).

빠르게 만들되 나중에 갈아엎지는 않고 싶을 때.

AI 기능(임베딩 검색)을 붙일 계획이 있을 때 — pgvector가 기본 제공.

신중해야 할 경우

초당 수만 건 쓰기 같은 극단적 쓰기 부하 — 단일 Postgres 인스턴스가 한계다.

권한 규칙이 매우 복잡하고 동적일 때 — RLS로 표현하면 성능과 가독성이 무너진다.

이미 성숙한 백엔드가 있고 잘 굴러갈 때.

멀티 리전 쓰기가 필수일 때 — 단일 프라이머리 구조다.

Postgres를 아무도 모르는 팀 — 배울 의지가 없으면 안티패턴만 쌓인다.

물어볼 질문 여섯 개.

  1. 우리 데이터는 관계형인가, 문서형인가?
  2. 권한 규칙을 SQL 한 줄로 쓸 수 있는 수준인가?
  3. 팀에 SQL을 읽고 쓸 사람이 최소 한 명 있는가?
  4. 예상 쓰기 부하가 단일 Postgres로 감당 가능한 범위인가?
  5. 데이터 소재지·규제 요구가 있는가?
  6. 나중에 옮겨야 한다면, 그 비용을 감당할 수 있는 형태인가?

6번에 자신 있게 “예”라고 답할 수 있는 BaaS는 드물다. 그게 Supabase의 차별점이다.

초반에는 사실이다. 대시보드 클릭으로 테이블을 만들고 supabase-js로 조회하면 SQL을 안 쓴다. 하지만 RLS 정책은 SQL 표현식이고, 성능 문제는 SQL로 진단하며, 조금 복잡한 조회는 결국 데이터베이스 함수(RPC)로 내려간다.

필요한 수준은 “쿼리 튜닝 전문가”가 아니라 select, join, where, 인덱스, 트랜잭션의 감각이다. 4장에서 그 최소 수준을 짚는다.

Supabase가 없애주는 건 CRUD 백엔드 — 만들고 읽고 고치고 지우는 기본 연산(Create·Read·Update·Delete)만 감싸는 서버 — 이지, 서버 코드 전부가 아니다. 여전히 서버가 필요한 일 —

  • 결제 처리와 웹훅 검증 (Stripe 시크릿을 브라우저에 둘 수 없다)
  • 외부 API 호출 중 키가 필요한 것 (LLM, 이메일 발송 등)
  • 여러 단계를 원자적으로 처리해야 하는 비즈니스 로직
  • 무거운 배치·집계 작업

이 코드는 Vercel의 Route Handler나 Supabase Edge Function에 들어간다. 어디에 둘지가 12장의 주제다.

RLS는 강력하지만 정확히 쓴 만큼만 지켜준다. 흔한 사고 목록 —

  • 테이블은 만들었는데 RLS를 안 켰다 → publishable key로 전체 조회 가능
  • using (true) 정책을 임시로 넣고 잊었다
  • secret key를 클라이언트 번들에 넣었다 → RLS를 통째로 우회당한다
  • 뷰나 security definer 함수로 우회 경로가 열려 있었다
플랜가격대략의 포함 범위
Free$0DB 500MB, 대역폭 5GB, 스토리지 1GB, MAU(Monthly Active Users, 월간 활성 사용자) 5만, 프로젝트 2개
Pro$25/월~디스크 8GB, 대역폭 250GB, 스토리지 100GB, 백업 7일, 컴퓨트 크레딧 $10
Team$599/월~Pro + 백업 14일, 보안 인증 대응(SOC2·ISO 27001), SLA(Service Level Agreement — 가동률 보장 계약) 지원
Enterprise별도전담 지원, 가동률 SLA, BYOC(Bring Your Own Cloud — 내 클라우드 계정 위에 설치)
  • Free 플랜은 1주일간 활동이 없으면 프로젝트가 일시정지된다. 데모용으로는 주의
  • 실제 비용은 플랜 요금보다 컴퓨트 애드온과 대역폭에서 갈린다 (15장)
  • 초과분은 종량제로 붙는다 — 대역폭, MAU 초과분 등

가격과 포함량은 자주 바뀐다. 도입 견적을 낼 때는 이 표를 고정값으로 쓰지 말고 공식 가격 페이지에서 플랜 요금 + 프로젝트별 컴퓨트 + 초과 사용량을 함께 다시 계산한다.

  • Supabase는 Postgres 플랫폼이다. BaaS는 포장이고, 알맹이는 관계형 DB다
  • Firebase와의 차이는 취향이 아니라 데이터 모델과 쿼리 능력의 차이다
  • 최대 강점: 배운 게 남고, 도구 생태계가 열려 있고, 나갈 길이 있다
  • 최대 약점: 극단적 쓰기 부하, 복잡한 동적 권한, 멀티 리전 쓰기
  • “백엔드가 사라진다”가 아니라 “CRUD 백엔드가 사라진다”