서버리스 + 엣지 컴퓨팅: Cloudflare Workers로 전 세계 300개 노드에서 5ms 응답 구현하기
솔직히 처음 "서버리스 + 엣지 컴퓨팅"이라는 말을 들었을 때, 그냥 마케팅 용어 두 개를 합쳐놓은 거 아닌가 싶었습니다. AWS Lambda로 API 하나 만들어두고 "이게 서버리스지!" 하고 만족하던 시절이 있었거든요. 그런데 콜드 스타트 때문에 첫 요청이 1초 넘게 걸리는 걸 보고 나서야, 뭔가 더 있겠다는 생각을 하게 됐습니다.
이 글을 읽고 나면, 서버리스와 엣지 컴퓨팅이 어떻게 결합되는지, 어떤 상황에서 써야 하고 어떤 함정을 피해야 하는지 실무 관점에서 파악할 수 있습니다. JWT 인증, 지역 기반 개인화, AI 추론까지 실제 코드와 함께 살펴볼 예정입니다.
엣지 컴퓨팅은 그 "뭔가"에 대한 답입니다. 단순히 함수를 클라우드에서 실행하는 게 아니라, 사용자가 있는 곳 바로 옆에서 실행하는 거죠. 서울에 있는 사용자에게 버지니아 데이터센터까지 왕복하라고 할 게 아니라, 서울 PoP(Point of Presence)에서 바로 처리하는 겁니다. 2026년 현재, 이 조합은 인증·개인화·AI 추론까지 프로덕션에서 쓰이는 표준 패턴이 됐습니다.
핵심 개념
서버리스와 엣지, 각자 뭘 해결하나
서버리스(Serverless) 는 서버 관리 없이 함수 단위로 코드를 배포·실행하는 모델입니다. 이벤트가 발생할 때만 실행되고, 클라우드 공급자가 스케일링을 알아서 처리합니다. AWS Lambda, Google Cloud Functions, Azure Functions가 대표적이죠.
엣지 컴퓨팅(Edge Computing) 은 데이터 처리를 중앙 데이터센터가 아닌 사용자에게 가장 가까운 네트워크 엣지(PoP)에서 수행하는 패러다임입니다. 데이터가 이동하는 물리적 거리를 줄여서 지연(latency)을 낮춥니다.
PoP(Point of Presence) 란 CDN이나 클라우드 공급자가 전 세계에 분산해둔 서버 거점을 말합니다. Cloudflare는 현재 300개 이상의 PoP를 운영하고 있습니다.
두 개념을 합치면? 서버리스 함수를 전 세계 300개 이상의 엣지 노드에서 실행합니다. 코드 배포의 단순함은 유지하면서, 실행 위치를 사용자 가까이로 끌어당기는 거죠.
콜드 스타트 문제를 어떻게 5ms까지 줄였나
기존 Lambda의 콜드 스타트가 100ms~1초까지 걸리는 이유는 컨테이너를 띄우는 오버헤드 때문입니다. 엣지 서버리스는 이 문제를 V8 Isolate로 해결했습니다.
V8 Isolate 는 Google Chrome이 쓰는 V8 엔진의 격리 단위입니다. Docker 컨테이너보다 훨씬 가볍고, 콜드 스타트 시간이 수 밀리초 수준입니다. Cloudflare Workers가 이 방식을 사용합니다.
Docker 컨테이너와 V8 Isolate를 직접 비교하면 차이가 확 납니다:
| 항목 | Docker 컨테이너 | V8 Isolate |
|---|---|---|
| 콜드 스타트 | 수백ms ~ 수초 | 수ms 이하 |
| 메모리 오버헤드 | 수십~수백MB | 수MB |
| 격리 단위 | OS 프로세스 수준 | JavaScript 엔진 수준 |
| 지원 언어 | 모든 언어 | JS/TS, Wasm |
한 가지 짚고 넘어갈 부분이 있습니다. V8 Isolate가 컨테이너보다 격리가 "강력하다"고 단순하게 말하기는 어렵습니다. 두 방식의 격리 단위 자체가 다르기 때문입니다. V8 Isolate는 JavaScript 엔진 수준의 격리라서 Spectre 류의 사이드채널 공격에 대한 별도 완화 조치가 필요하고, Cloudflare도 이를 위한 추가 작업을 자체적으로 운영하고 있습니다. "콜드 스타트 속도와 경량성은 V8 Isolate, OS 수준 프로세스 격리는 컨테이너"라고 이해하는 게 정확합니다.
WebAssembly가 게임 체인저인 이유
V8 Isolate가 JS/TS에 최적화된 반면, WebAssembly(Wasm) 는 언어에 중립적인 바이너리 포맷입니다. Rust, Go, C++로 짠 코드를 Wasm으로 컴파일하면 엣지에서도 네이티브에 가까운 성능으로 실행됩니다.
2025년 초 출시된 WASI 0.3부터는 네이티브 async 지원이 추가됐고, 2026년 2월에는 Llama-3-8b 모델이 Wasm 기반 V8 Isolate로 330여 개 위치에 배포되어 콜드 스타트 5ms 미만으로 AI 추론을 제공한 사례도 나왔습니다. 엣지에서 AI 추론이 현실이 된 거죠.
WASI(WebAssembly System Interface) 는 Wasm이 파일 시스템, 네트워크 등 OS 자원에 안전하게 접근하기 위한 표준 인터페이스입니다. "브라우저 밖의 Wasm"을 가능하게 해주는 핵심 표준입니다.
실전 적용
이제 이 개념들이 실제 코드에서 어떻게 생겼는지 살펴보겠습니다. 아래 예시들은 모두 Cloudflare Workers 프로젝트를 기반으로 합니다. Hono는 Cloudflare Workers, Deno, Node.js, Bun 전반을 지원하는 초경량 웹 프레임워크인데, 엣지 환경에서 Express처럼 쓸 수 있다고 생각하시면 됩니다. 프로젝트 생성은 pnpm create cloudflare@latest로 시작할 수 있습니다.
예시 1: 엣지에서 JWT 인증 처리하기
저도 처음엔 헷갈렸는데, 인증은 엣지 서버리스의 교과서적인 활용 사례입니다. 사용자 요청이 오리진 서버에 닿기 전에 가장 가까운 엣지 노드에서 JWT를 검증하면, 원거리 데이터센터 왕복 없이 인증이 끝납니다.
Cloudflare Workers + Hono로 구현하면 이런 형태가 됩니다:
import { Hono } from 'hono'
import { jwt } from 'hono/jwt'
// Env 타입은 wrangler.toml의 바인딩 변수를 반영합니다
type Env = {
JWT_SECRET: string
}
const app = new Hono<{ Bindings: Env }>()
// JWT 검증 미들웨어 — 시크릿은 반드시 환경 변수에서 주입
app.use('/api/*', (c, next) => {
return jwt({ secret: c.env.JWT_SECRET })(c, next)
})
app.get('/api/user/profile', async (c) => {
const payload = c.get('jwtPayload')
// 검증 통과한 요청만 오리진으로 프록시
const response = await fetch(`https://origin.example.com/user/${payload.sub}`, {
headers: { 'X-User-Id': payload.sub }
})
return response
})
export default app| 코드 포인트 | 설명 |
|---|---|
c.env.JWT_SECRET |
시크릿을 코드에 직접 쓰면 보안 취약점이 됩니다. Cloudflare Workers의 Secret 환경 변수에서 주입하는 방식을 권장합니다 |
hono/jwt |
Hono의 내장 JWT 미들웨어로, 엣지 런타임에서 동작합니다 |
c.get('jwtPayload') |
검증된 페이로드를 컨텍스트에서 꺼내 씁니다 |
fetch(origin...) |
검증 통과 후에만 오리진 서버를 호출합니다 |
Next.js를 쓰고 있다면 middleware.ts에서 엣지 배포가 가능합니다. jose는 엣지 런타임에서 동작하는 대표적인 JWT 라이브러리입니다:
// middleware.ts — jose 라이브러리로 엣지 JWT 검증 예시
import { jwtVerify } from 'jose'
import { NextRequest, NextResponse } from 'next/server'
export const config = {
matcher: '/api/:path*',
runtime: 'edge', // 이 한 줄로 엣지 배포
}
export async function middleware(request: NextRequest) {
const token = request.headers.get('Authorization')?.replace('Bearer ', '')
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
try {
// jose는 Web Crypto API 기반이라 엣지 런타임에서 동작합니다
const secret = new TextEncoder().encode(process.env.JWT_SECRET)
await jwtVerify(token, secret)
return NextResponse.next()
} catch {
return NextResponse.json({ error: 'Invalid token' }, { status: 403 })
}
}예시 2: 지역·디바이스 기반 콘텐츠 개인화
A/B 테스트를 처음 엣지로 옮겼을 때 오리진 부하가 눈에 띄게 줄었던 경험이 있습니다. 지역별 콘텐츠 분기를 엣지에서 처리하면 중앙 서버 부하 없이 글로벌 개인화가 됩니다.
// Cloudflare Workers — 지역 기반 콘텐츠 분기
// wrangler.toml에 별도 AI 바인딩 없이 request.cf 메타데이터만으로 동작합니다
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const cf = (request as any).cf // Cloudflare가 자동으로 붙여주는 메타데이터
const country = cf?.country ?? 'US'
const device = cf?.deviceType ?? 'desktop'
// 지역·디바이스 조합으로 캐시 키 생성
const cacheKey = new Request(
`${request.url}?country=${country}&device=${device}`,
request
)
const cache = caches.default
let response = await cache.match(cacheKey)
if (!response) {
response = await fetch(`https://origin.example.com${new URL(request.url).pathname}`, {
headers: {
'X-Country': country,
'X-Device': device,
}
})
// ctx가 없으면 이 줄에서 런타임 에러가 납니다 — 세 번째 매개변수 필수
const cacheResponse = response.clone()
ctx.waitUntil(cache.put(cacheKey, cacheResponse))
}
return response
}
}| 코드 포인트 | 설명 |
|---|---|
ctx: ExecutionContext |
세 번째 매개변수로 반드시 선언해야 합니다. ctx.waitUntil을 쓰려면 빠질 수 없습니다 |
request.cf |
Cloudflare가 자동으로 붙여주는 지역·디바이스 메타데이터로, 별도 설정 없이 사용 가능합니다 |
caches.default |
Cloudflare의 엣지 캐시 API입니다 |
ctx.waitUntil |
응답을 먼저 반환하고 백그라운드에서 캐시를 저장합니다. 응답 속도에 영향을 주지 않습니다 |
예시 3: 엣지 AI 추론 엔드포인트
Cloudflare Workers AI를 활용하면 ML 모델 추론을 엣지에서 직접 실행할 수 있습니다. 아래 예시는 wrangler.toml에 AI 바인딩([ai])이 설정된 상태를 가정하며, 입력 검증과 에러 처리를 포함한 형태로 구성했습니다:
// Workers AI — 텍스트 감성 분석 엣지 추론
// wrangler.toml: [ai] binding = "AI" 설정이 필요합니다
type Env = {
AI: Ai
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.method !== 'POST') {
return Response.json({ error: 'Method not allowed' }, { status: 405 })
}
let text: string
try {
const body = await request.json() as { text?: string }
if (!body.text) {
return Response.json({ error: 'text field is required' }, { status: 400 })
}
text = body.text
} catch {
return Response.json({ error: 'Invalid JSON' }, { status: 400 })
}
const result = await env.AI.run('@cf/huggingface/distilbert-sst-2-int8', { text })
return Response.json({
sentiment: result[0].label,
confidence: result[0].score,
})
}
}모델 추론이 사용자 가까운 엣지에서 실행되므로, 중앙 AI 서버로의 왕복 없이 일관된 낮은 레이턴시를 제공합니다. 스트리밍 응답이나 상태 저장이 필요한 패턴은 Durable Objects 영역의 이야기로, 이 예시보다 한 단계 더 복잡해집니다.
장단점 분석
장점
장단점 표만 보면 엣지가 무조건 좋아 보입니다. 실제로도 레이턴시 민감한 워크로드에서는 체감 차이가 크지만, 그만큼 예상치 못한 제약도 있어서 맥락과 함께 보시면 좋습니다.
| 항목 | 내용 |
|---|---|
| 빠른 콜드 스타트 | Cloudflare Workers 기준 콜드 스타트 5ms 미만 (기존 Lambda 100ms~1s 대비) |
| 낮은 레이턴시 | 사용자와 물리적으로 가까운 엣지 실행으로 왕복 시간 대폭 감소 |
| 비용 효율 | 월 1,000만 요청 기준 Cloudflare Workers ~$5 vs AWS Lambda@Edge ~$17 (약 70% 절감, 공개 가격 기준) |
| 자동 스케일링 | 트래픽 급증 시 수동 개입 없이 자동 확장 |
| 데이터 주권 | 특정 국가·지역 엣지에서만 처리되도록 강제 가능 |
비용 비교($5 vs $17)는 공개된 가격 기반이지만, 레이턴시 개선 수치는 워크로드와 배포 환경에 따라 크게 달라집니다. "우리 서비스에서 실제로 얼마나 개선됐나"는 직접 측정해보는 게 가장 정확합니다.
단점 및 주의사항
실제로 Node.js 패키지 호환 문제는 처음 엣지로 넘어올 때 거의 모든 팀이 한 번은 겪습니다. 아래 표에 실제 대응 방안과 함께 정리했습니다.
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| 실행 환경 제약 | Edge Runtime은 Node.js API 서브셋만 지원, 네이티브 모듈·파일 시스템 불가 | 엣지 친화적 라이브러리(Hono, jose 등) 선택 |
| 상태 관리 어려움 | 각 함수 호출이 무상태(stateless) | Cloudflare KV/D1/Durable Objects, Upstash Redis 활용 |
| 복잡한 워크로드 한계 | CPU·메모리 집약 작업은 전통적 서버리스가 유리 | 하이브리드 아키텍처 (엣지: 라우팅·인증, 오리진: 처리) |
| 디버깅 어려움 | 분산 엣지 환경에서 로컬 재현이 어려움 | wrangler dev로 로컬 에뮬레이션, 구조화된 로그 활용 |
| 벤더 종속 | 플랫폼별 런타임 차이로 이식성 문제 발생 가능 | Hono처럼 멀티 런타임 지원 프레임워크 선택 |
| 보안 트레이드오프 | V8 Isolate(JS 엔진 수준)와 컨테이너(OS 프로세스 수준)는 격리 단위가 달라 각각의 보안 특성이 다름 | 사이드채널 공격 완화는 플랫폼(Cloudflare) 측 조치에 의존 |
Durable Objects 는 Cloudflare가 제공하는 상태 저장 가능한 엣지 객체입니다. 각 객체가 특정 지역에 고정되어 상태를 유지할 수 있어, 무상태 엣지 함수의 한계를 보완합니다.
실무에서 가장 흔한 실수
-
Node.js 패키지를 그냥 들고 오기 —
fs,crypto,path같은 Node.js 내장 모듈이나 네이티브 애드온이 포함된 패키지는 Edge Runtime에서 동작하지 않습니다. 패키지 선택 단계부터 엣지 호환 여부를 확인하는 것을 권장합니다. -
엣지에서 모든 걸 처리하려는 욕심 — 엣지는 빠른 I/O와 경량 연산에 최적화돼 있습니다. 무거운 이미지 처리, 복잡한 트랜잭션, 장시간 실행 작업을 엣지에 올리면 오히려 제약만 만납니다. 장시간 실행 워크로드는 컨테이너, 버스트 트래픽은 엣지로 나누는 하이브리드가 현재 표준입니다.
-
상태 관리를 간과하기 — "이건 간단하니까 인메모리로 충분해"라고 생각했다가 Isolate가 재사용되지 않으면 상태가 사라지는 걸 프로덕션에서 경험하는 경우가 있습니다. 상태가 필요하다면 처음부터 KV 스토어나 Durable Objects를 설계에 포함시키는 편이 훨씬 낫습니다.
마치며
레이턴시가 UX에 직결되는 워크로드라면 — 인증, 개인화, AI 추론 같은 — 엣지를 기본 선택지로 고려해보는 게 지금의 표준입니다. "나중에 최적화하자"보다, 처음 설계할 때 엣지로 처리할 수 있는 레이어를 분리해두면 나중에 훨씬 수월해집니다.
처음 시작이 막막하게 느껴진다면 아래 순서로 접근해 보시면 좋습니다.
-
Cloudflare Workers 무료 플랜에서 Hello World 배포해보기 —
pnpm create cloudflare@latest로 프로젝트를 만들고wrangler deploy로 실제 엣지 배포를 경험해 볼 수 있습니다. Cloudflare 계정 생성과wrangler login이 필요한데, Cloudflare Workers 시작 공식 문서에 단계별 안내가 잘 정리돼 있습니다. 콜드 스타트 차이가 체감됩니다. -
기존 Next.js 미들웨어를 엣지로 전환해보기 —
middleware.ts에export const runtime = 'edge'를 추가하는 것만으로 시작할 수 있습니다. 인증 로직을 여기로 옮기면 오리진 부하가 눈에 띄게 줄어드는 걸 확인할 수 있습니다. -
Hono 프레임워크로 멀티 런타임 API 작성해보기 — Hono는 Cloudflare Workers, Deno Deploy, Node.js, Bun 모두를 지원하므로, 한 번 작성한 코드로 여러 플랫폼을 경험해 볼 수 있습니다. 벤더 종속 걱정 없이 엣지 API의 구조를 익히기에 좋은 출발점입니다.
참고 자료
개념 및 트렌드
- Serverless Edge Computing: A Taxonomy, Systematic Literature Review, Current Trends and Research Challenges | arXiv
- The Edge Effect: Serverless & Deployment Redefined in 2026 | Apex Logic
- WebAssembly's Edge Revolution: How WASM is Redefining Serverless Computing in 2025 | Medium
플랫폼 비교