본문으로 건너뛰기
← 블로그로 돌아가기
개발 2025년 11월 20일

Cloudflare 무료 스택으로 SaaS 운영하기 — Pages + Workers + KV + R2

서버 비용 0원으로 SaaS를 운영하는 Cloudflare 무료 스택 구성과 실전 경험.

Cloudflare SaaS 서버리스 무료 스택

무료로 SaaS를 운영할 수 있는가

결론부터: MVP 단계에서는 가능하다. Cloudflare의 무료 티어가 놀라울 정도로 넉넉하다.

서비스무료 한도용도
Pages빌드 500회/월, 대역폭 무제한프론트엔드 호스팅
Workers10만 요청/일, 10ms CPUAPI 서버
KV읽기 10만/일, 쓰기 1,000/일캐시, 설정 데이터
R2저장 10GB, 읽기 1,000만/월파일 스토리지
D15GB, 읽기 500만/일SQLite 데이터베이스

일일 사용자 100명 이하의 SaaS는 이 한도 안에서 충분히 운영된다.

아키텍처

사용자 브라우저

Cloudflare Pages (프론트엔드)

Cloudflare Workers (API)
    ├── KV (세션, 캐시)
    ├── D1 (사용자 데이터)
    └── R2 (파일 업로드)

모든 서비스가 Cloudflare 네트워크 안에서 동작하므로, 서비스 간 통신 지연이 극히 작다. 외부 DB(Supabase, PlanetScale)를 사용하면 네트워크 왕복이 추가되지만, D1은 Workers와 같은 엣지에서 동작한다.

Pages — 프론트엔드

Astro, Next.js, React 등 어떤 프레임워크든 배포할 수 있다. GitHub 연결 후 push만 하면 자동 배포된다.

무제한 대역폭이 핵심이다. Vercel이나 Netlify는 무료 티어에 대역폭 제한이 있지만, Cloudflare Pages는 없다.

Workers — API 서버

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);

    if (url.pathname.startsWith('/api/')) {
      return handleApi(request, env);
    }

    return env.ASSETS.fetch(request);
  },
};

Workers의 제한 사항:

  • CPU 시간 10ms (무료) / 30초 (유료): AI API 호출처럼 대기 시간이 긴 작업은 CPU를 거의 안 쓰므로 괜찮다
  • 메모리 128MB: 대용량 데이터 처리에는 부적합
  • 번들 크기 3MB (무료): 라이브러리를 최소화해야 한다

KV — 키-값 저장소

세션 토큰, API 응답 캐시, 기능 플래그 등에 사용한다.

// 캐시 저장
await env.CACHE.put('exchange-rate', JSON.stringify(rate), {
  expirationTtl: 3600, // 1시간
});

// 캐시 조회
const cached = await env.CACHE.get('exchange-rate', 'json');
if (cached) return Response.json(cached);

KV는 읽기가 매우 빠르고(엣지 캐시), 쓰기는 전파에 시간이 걸린다. “읽기 많고 쓰기 적은” 데이터에 최적이다.

D1 — SQLite 데이터베이스

Workers에서 SQL을 쓸 수 있다. 로컬의 SQLite와 동일한 문법이다.

const result = await env.DB.prepare(
  'SELECT * FROM users WHERE email = ?'
).bind(email).first();

D1은 아직 베타지만, 간단한 CRUD에는 충분하다. 복잡한 쿼리나 대용량 데이터는 Supabase나 Turso가 낫다.

R2 — 파일 스토리지

S3 호환 API를 제공한다. 이미지, PDF, 사용자 업로드 파일을 저장한다.

// 파일 업로드
await env.BUCKET.put(`uploads/${userId}/${filename}`, file);

// 파일 조회
const object = await env.BUCKET.get(`uploads/${userId}/${filename}`);
if (object) {
  return new Response(object.body, {
    headers: { 'Content-Type': object.httpMetadata?.contentType ?? '' },
  });
}

S3와 달리 이그레스 비용(데이터 전송 비용)이 없다. 이미지가 많은 서비스에서 비용 절약이 크다.

비용이 발생하는 시점

무료 한도를 넘으면 유료 플랜으로 전환해야 한다. Workers Paid 플랜은 $5/월부터.

넘기 쉬운 한도:

  • KV 쓰기 1,000회/일: 사용자가 늘면 빠르게 도달
  • Workers 10만 요청/일: API 호출이 많은 서비스는 수일 내 도달
  • D1 쓰기: 트랜잭션이 많으면 한도에 걸림

MVP에서 유료 전환까지의 기간은 서비스 특성에 따라 다르지만, 보통 사용자 수백 명 수준에서 전환이 필요하다.

실전 팁

  • 환경 분리: wrangler.toml에서 [env.staging][env.production]을 분리
  • 로컬 개발: wrangler dev로 로컬에서 Workers + KV + D1을 에뮬레이션
  • 모니터링: Cloudflare 대시보드에서 요청 수, 에러율, 지연 시간 확인
  • 보안: Workers에서 CORS, Rate Limiting, API 키 검증을 직접 구현

정리

Cloudflare의 무료 스택은 MVP를 검증하기에 충분하다. 서버 비용 0원으로 프론트엔드, API, DB, 스토리지를 모두 커버한다. 사용자가 늘어도 유료 플랜의 가격이 합리적이어서, 초기 스타트업에 적합한 인프라다.