【실제 경험】Vercel/Supabase 무료 플랜으로 월 수백 엔 이내로 억제하는 구성과 함정
요약
Vercel과 Supabase의 무료 플랜을 활용하여 월 비용을 최소화하는 구체적인 방법과 주의사항을 다룹니다. 프로젝트 자동 정지 방지, 서버리스 함수 타임아웃 설정, RLS 보안 및 대역폭 절약 전략을 제시합니다.
핵심 포인트
- Supabase 무료 프로젝트의 7일 미사용 시 자동 정지 방지를 위한 pg_cron 또는 GitHub Actions 활용
- Vercel Serverless Function의 타임아웃 설정을 통한 무한 루프 및 에러 방지
- 데이터 유출 방지를 위한 Supabase RLS(Row Level Security) 활성화 필수
- Supabase Storage 이미지 변환 API 사용을 지양하여 요청 횟수 및 비용 절감
Vercel/Supabase 무료 플랜으로 월 수백 엔 이내로 억제하는 구성과 함정
결론
올바르게 설정하면 Vercel + Supabase의 월간 비용은 거의 ¥0으로 운영할 수 있다. 하지만 「무료 플랜을 초과하는 순간 과금이 시작되는」 함정이 여러 개 있어, 아무 생각 없이 사용하면 월 수천 엔이 나올 수 있다. 이 기사에서는 구체적인 제한 수치와 초과를 방지하기 위한 설정을 제시한다.
무료 플랜의 실제 수치
Vercel (Hobby Plan)
| 항목 | 상한 |
|---|---|
| Bandwidth | 100 GB/월 |
| ... |
Supabase (Free Plan)
| 항목 | 상한 |
|---|---|
| DB Storage | 500 MB |
| ... |
함정 1: Supabase의 자동 정지
무료 프로젝트는 7일간 액세스가 없으면 자동으로 정지된다.
대책은 pg_cron으로 정기적으로 더미 쿼리 (Dummy Query)를 던지는 것이다.
-- Supabase SQL Editor 에서 실행
select cron.schedule(
'keep-alive',
...
또는 GitHub Actions로 외부에서 호출한다.
# .github/workflows/keep-alive.yml
name: Supabase Keep Alive
on:
...
함정 2: Vercel의 Serverless Function이 무한 루프
Edge/Serverless Function 내에서 외부 API를 호출할 때, 타임아웃 (Timeout) 설정을 잊으면 10초 제한에 걸려 429/500 에러가 빈번하게 발생하고 리트라이 (Retry)가 쌓이게 된다.
// NG: 타임아웃 미설정
const res = await fetch('https://api.example.com/data')
...
vercel.json에서 Function의 maxDuration을 명시한다.
{
"functions": {
"api/**/*.ts": {
...
함정 3: Supabase의 Row Level Security를 해제하면 모든 데이터가 유출됨
무료 플랜·유료 플랜에 관계없이, RLS (Row Level Security)를 비활성화한 채로 테이블을 공개하면 anon 키로 모든 행이 SELECT 된다.
-- 반드시 RLS를 활성화할 것
alter table posts enable row level security;
...
supabase db diff로 정책 차분을 로컬에서 확인하는 습관을 들인다.
npx supabase db diff --schema public
권장 구성: 월 0엔으로 억제하는 최소 스택
Next.js (App Router)
└─ Static Pages → Vercel CDN (대역폭을 거의 소비하지 않음)
└─ API Routes → Vercel Functions (월 100k회면 충분)
...
대역폭을 절약하는 캐시 설정
// next.config.js
module.exports = {
async headers() {
...
Supabase Storage의 이미지는 변환 API를 사용하지 않는다
/storage/v1/render/image/ 변환 엔드포인트는 변환 1회당 카운트된다. 무료 플랜에서는 가공되지 않은 URL을 반환하고 프론트엔드에서 <img width> 리사이즈(Resize)에 그치도록 한다.
// NG: 변환 API 경유 → 요청 소비
const url = supabase.storage.from('images').getPublicUrl('photo.jpg', {
transform: { width: 400 }
...
모니터링: 초과 전에 알아차리기
Vercel은 Usage 페이지에 임계값 알림 (Threshold Alert)이 없으므로, 수동으로 확인하거나 Vercel API로 가져온다.
# Vercel 사용량 확인
curl -s "https://api.vercel.com/v2/usage" \
-H "Authorization: Bearer $VERCEL_TOKEN" | jq '.bandwidth.used'
Supabase는 대시보드 Project Settings > Usage에서 확인한다. 월 15일경에 사용량이 절반을 초과했다면 포스팅 빈도를 낮춘다.
요약
- Supabase에는 7일 keep-alive를 설정할 것 (자동 정지가 가장 큰 함정)
- Function은 8초 타임아웃 필수 (재시도(Retry) 폭발 방지)
- RLS(Row Level Security)는 절대로 비활성화하지 말 것
- Storage 변환 API는 사용하지 말 것
- 대역폭(Bandwidth)은 Cache-Control로 절감할 것
이 4가지를 지키면 개인 서비스는 월 0엔으로도 충분히 운영 가능하다. 스케일 업(Scale)하여 무료 범위를 초과했을 때는, Supabase Pro($25/월)로 넘어가기 전에 불필요한 실시간 연결(Realtime connection)과 Storage 트리거를 제거함으로써 운영 기간을 연장할 수 있다.
관련 링크
※ 자사 상품 (프로모션 포함).
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기