Cloudflare Workers 실전 가이드 — 엣지 컴퓨팅 입문
Cloudflare Workers의 개념, Wrangler CLI, KV/D1/R2 스토리지, Hono 프레임워크, 배포와 비용 비교.
한 줄 요약: Cloudflare Workers는 V8 엔진 위에서 동작하는 엣지 런타임으로, 전 세계 330개 PoP에서 콜드 스타트 없이 실행된다. AWS Lambda 대비 레이턴시가 낮고, KV/D1/R2 스토리지와 결합하면 서버리스 풀스택 앱을 구축할 수 있다.
- 엣지 컴퓨팅의 개념을 실전 코드와 함께 이해하고 싶은 개발자
- Wrangler CLI로 Workers 프로젝트를 처음 셋업하려는 경우
- KV, D1, R2 스토리지 중 어떤 것을 써야 하는지 판단 기준이 필요한 경우
- AWS Lambda와 Cloudflare Workers의 차이를 비교하고 싶은 경우
Cloudflare Workers란 무엇인가
Cloudflare Workers는 Cloudflare CDN 네트워크 위에서 JavaScript(및 WebAssembly)를 실행하는 서버리스 플랫폼이다. Node.js나 Deno와 달리 V8 Isolate 기반으로 동작하며, 각 요청이 독립된 격리 환경에서 실행된다.
핵심 특징
- 콜드 스타트 없음: V8 Isolate는 컨테이너를 스핀업하지 않기 때문에 AWS Lambda에서 발생하는 수백 ms 콜드 스타트가 없다. 공식 측정 기준 0ms 콜드 스타트.
- 엣지 실행: 요청이 사용자와 가장 가까운 Cloudflare PoP(Points of Presence)에서 처리된다. 전 세계 330개+ 데이터센터.
- 제한된 런타임: Node.js API 전체를 지원하지 않는다. fs, child_process 등 OS 레벨 API는 없고, Fetch API, Web Crypto, Streams API 등 Web Standard API를 사용한다.
- 비용 구조: 무료 티어에서 일 10만 요청까지 무료. 이후 $0.50/100만 요청. AWS Lambda 대비 훨씬 저렴하다.
| 항목 | Cloudflare Workers | AWS Lambda |
|---|---|---|
| 실행 환경 | V8 Isolate | 컨테이너 |
| 콜드 스타트 | ~0ms | 100ms~수 초 |
| 실행 위치 | 엣지 (글로벌) | 리전 선택 |
| 런타임 | Web Standards API | Node.js / Python 등 |
| 최대 실행 시간 | 30초 (CPU 시간) | 15분 |
| 무료 티어 | 일 10만 요청 | 월 100만 요청 |
| VPC/네트워크 통합 | 제한적 | 완전 지원 |
Wrangler CLI로 첫 Workers 프로젝트 셋업
Wrangler는 Cloudflare Workers의 공식 CLI 도구다. 로컬 개발, 테스트, 배포를 단일 CLI로 처리한다.
Wrangler 설치 및 프로젝트 초기화# Wrangler CLI 설치 npm install -g wrangler # Cloudflare 계정 로그인 wrangler login # 새 Workers 프로젝트 생성 (TypeScript 템플릿) npm create cloudflare@latest my-worker -- --type=hello-world-typescript cd my-worker # 로컬 개발 서버 시작 (http://localhost:8787) wrangler dev # 프로덕션 배포 wrangler deploy
src/index.ts — 기본 Workers 핸들러 구조export interface Env { MY_KV: KVNamespace MY_DB: D1Database MY_BUCKET: R2Bucket // 환경 변수 API_KEY: string } export default { async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> { const url = new URL(request.url) // 라우팅 예시 if (url.pathname === '/api/hello') { return Response.json({ message: 'Hello from the Edge!' }) } if (url.pathname === '/api/kv' && request.method === 'GET') { const value = await env.MY_KV.get('my-key') return Response.json({ value }) } return new Response('Not Found', { status: 404 }) } }
wrangler dev --local을 사용하면 KV, D1, R2 등 바인딩도 로컬에서 시뮬레이션된다. Miniflare가 내장되어 있어 실제 엣지 환경과 거의 동일한 조건으로 테스트할 수 있다.KV / D1 / R2 — 스토리지 선택 기준
Cloudflare는 Workers에서 사용할 수 있는 3가지 스토리지를 제공한다. 각각 용도가 다르므로 선택 기준을 명확히 알아야 한다.
KV (Key-Value Store)
전 세계에 복제되는 Eventually Consistent 키-값 스토어다. 읽기 성능이 극도로 빠르지만 쓰기 후 전파에 최대 60초가 걸릴 수 있다.
- 적합한 사용: 세션 토큰, 설정 캐시, 공개 콘텐츠 캐싱, 피처 플래그
- 부적합한 사용: 금융 트랜잭션, 실시간 카운터, 강한 일관성이 필요한 데이터
D1 (SQLite 호환 관계형 DB)
엣지에서 동작하는 SQLite 호환 데이터베이스다. Workers와 같은 지역에 복제본이 생성되어 낮은 레이턴시를 유지한다.
- 적합한 사용: 사용자 데이터, 앱 상태, 관계형 쿼리가 필요한 모든 것
- 제한: DB 크기 최대 10GB (유료), 읽기 전용 복제본은 전 세계 분산, 쓰기는 단일 리전
R2 (S3 호환 오브젝트 스토리지)
S3 API 호환 오브젝트 스토리지로, AWS S3 대비 이그레스(데이터 전송) 비용이 없다.
- 적합한 사용: 파일 업로드/다운로드, 이미지 저장, 정적 에셋 서빙
- 비용: 저장 $0.015/GB/월, 쓰기 $4.50/백만 요청, 읽기 $0.36/백만 요청
D1 데이터베이스 — wrangler.toml 설정 및 쿼리 예시# wrangler.toml [[d1_databases]] binding = "MY_DB" database_name = "my-app-db" database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # D1 마이그레이션 파일 생성 # migrations/0001_create_users.sql
D1 쿼리 실전 예시 — Workers에서 SQLite 사용// Workers에서 D1 쿼리 export default { async fetch(request: Request, env: Env): Promise<Response> { if (request.method === 'POST' && new URL(request.url).pathname === '/api/users') { const { name, email } = await request.json() as { name: string; email: string } // D1에 데이터 삽입 const result = await env.MY_DB .prepare('INSERT INTO users (name, email) VALUES (?1, ?2) RETURNING id') .bind(name, email) .first<{ id: number }>() return Response.json({ id: result?.id }, { status: 201 }) } if (request.method === 'GET' && new URL(request.url).pathname === '/api/users') { const users = await env.MY_DB .prepare('SELECT id, name, email FROM users ORDER BY id DESC LIMIT 50') .all() return Response.json(users.results) } return new Response('Not Found', { status: 404 }) } }
Hono 프레임워크 — Workers에서 Express처럼 개발하기
Hono는 Web Standards API 기반의 경량 웹 프레임워크로, Cloudflare Workers, Deno, Bun, Node.js 등 다양한 런타임에서 동일한 코드로 동작한다. Workers 위에서 Express 스타일로 라우팅, 미들웨어, 유효성 검사를 처리할 수 있다.
Hono로 REST API 구축 — Workers 실전 예시import { Hono } from 'hono' import { zValidator } from '@hono/zod-validator' import { z } from 'zod' const app = new Hono<{ Bindings: Env }>() // 미들웨어 — API Key 인증 app.use('/api/*', async (c, next) => { const apiKey = c.req.header('x-api-key') if (apiKey !== c.env.API_KEY) { return c.json({ error: 'Unauthorized' }, 401) } await next() }) const userSchema = z.object({ name: z.string().min(1).max(100), email: z.string().email(), }) app.post('/api/users', zValidator('json', userSchema), async (c) => { const { name, email } = c.req.valid('json') const result = await c.env.MY_DB .prepare('INSERT INTO users (name, email) VALUES (?1, ?2) RETURNING id') .bind(name, email) .first<{ id: number }>() return c.json({ id: result?.id }, 201) }) app.get('/api/users/:id', async (c) => { const id = c.req.param('id') const user = await c.env.MY_DB .prepare('SELECT * FROM users WHERE id = ?') .bind(id) .first() if (!user) return c.json({ error: 'Not found' }, 404) return c.json(user) }) export default app
Workers가 맞는 경우, 맞지 않는 경우
Cloudflare Workers가 모든 워크로드에 최적은 아니다. 선택 전에 다음 기준을 확인하라.
Workers가 유리한 경우
- 전 세계 사용자에게 낮은 레이턴시 API를 제공해야 할 때
- 고빈도 단순 요청 처리 (리다이렉트, 헤더 조작, 경량 JSON API)
- 엣지에서 A/B 테스트, 지역별 콘텐츠 분기
- Cloudflare 네트워크를 이미 사용 중인 경우 (CDN, DNS)
Workers가 부적합한 경우
- 긴 실행 시간이 필요한 작업 (비디오 처리, ML 추론): CPU 시간 30초 제한
- Node.js 전용 라이브러리를 사용해야 하는 경우: fs, native addon 불가
- 프라이빗 VPC 내 데이터베이스 직접 연결: Workers는 퍼블릭 인터넷 기반
- 대용량 파일 처리 (메모리 128MB 제한)
@hono/node-server 어댑터를 사용하면 같은 코드베이스로 로컬 Node.js와 Cloudflare Workers 양쪽을 모두 지원할 수 있다.