Split View: CDN 완벽 가이드 — Cache, Edge Compute, Origin Shield, HTTP 캐싱 헤더 모든 것 (2025)
CDN 완벽 가이드 — Cache, Edge Compute, Origin Shield, HTTP 캐싱 헤더 모든 것 (2025)
들어가며 — 당신이 보는 웹의 99%는 Edge에서 온다
2026년 현재 주요 웹사이트에 접속하면, 당신이 받는 바이트의 거의 전부는 original 서버가 아니라 edge 서버에서 온다. Cloudflare는 전 세계 300+ 도시, Akamai는 4,000+ 위치, Fastly는 수십 개 주요 PoP에 서버를 둔다. 이 edge 서버들이 HTML, 이미지, JS, 비디오를 캐시하고, 실시간 규칙 변환을 적용하고, TLS를 종료하고, DDoS를 흡수한다.
이 계층 없이 현대 웹은 불가능하다. Netflix가 하루 1EB를 스트리밍하면서 origin 서버를 망가뜨리지 않는 이유는 edge 때문이다. 쇼핑몰이 블랙프라이데이에 1000배 트래픽을 견디는 이유, 뉴스 사이트가 기사 하나가 바이럴 될 때 살아남는 이유, 전 세계 사용자가 비슷한 latency로 웹을 쓸 수 있는 이유 — 전부 CDN의 edge caching이 있기에 가능하다.
이 글은 CDN의 모든 것을 1,500줄에 걸쳐 파헤친다. 1998년 Akamai의 탄생, 라우팅의 삼위일체(Anycast + DNS + GSLB), PoP의 물리적 구조, Cache Key 설계의 미묘함, HTTP 캐싱 헤더의 정확한 의미, Origin Shield로 origin을 보호하는 법, Edge Compute의 실행 모델, Image 최적화의 내부 동작, 대역폭 비용 경제학, DDoS 흡수 메커니즘, 그리고 현장의 실제 운영 노하우까지.
이 글은 DNS 글의 자연스러운 후속이다. DNS가 사용자를 edge PoP으로 라우팅한 다음에 일어나는 일을 바이트 수준에서 그린다.
1. CDN의 짧은 역사
1.1 Akamai의 탄생
1995년 MIT 수학 교수 Tom Leighton과 박사과정 학생 Danny Lewin이 "어떻게 하면 웹 콘텐츠를 전 세계에 빠르게 배포할까"를 연구한다. 그들의 아이디어는 수학적이었다: consistent hashing으로 콘텐츠를 여러 서버에 분산하고, 사용자를 가장 가까운 서버로 라우팅하라.
1998년 Akamai Technologies 창업. 1999년 슈퍼볼 중계 웹사이트가 다운됐을 때 Akamai가 트래픽을 처리하면서 CDN이라는 개념이 업계에 알려졌다.
2001년 9/11 테러 때 대형 뉴스 사이트들이 Akamai 덕에 살아남는다. 그 후 CNN, ESPN, Fox News가 Akamai를 표준으로 채택.
1.2 새로운 세대
- 2000년대 중반: CloudFront, Limelight, EdgeCast 등장.
- 2010년: Cloudflare 창업. "DDoS 보호 + CDN"을 무료 플랜으로 번들.
- 2011년: Fastly 창업. "Instant Purge" — 150ms 안에 전 세계 캐시 무효화.
- 2017년: Cloudflare Workers 발표. V8 Isolate 기반 edge compute.
- 2019년: Fastly Compute@Edge. WebAssembly + Rust 기반.
- 2020–2024년: Netflix, AWS, Meta가 자체 CDN을 구축하는 흐름.
2026년 현재 주요 플레이어:
- Cloudflare: 점유율 1위, 개발자 친화적, edge compute 선도.
- Akamai: 엔터프라이즈 지배, 보안 제품군.
- Fastly: 성능 선도, 개발자 친화적.
- Amazon CloudFront: AWS 통합, 가격 경쟁력.
- Google Cloud CDN, Microsoft Azure CDN, Bunny.net, KeyCDN 등.
1.3 왜 CDN이 필요한가 (라텐시의 수학)
빛은 1초에 30만 km. 광섬유에서는 그 2/3 속도. 서울에서 뉴욕까지 편도 11,000km → 최소 55ms RTT는 110ms. 실제로는 라우팅 hop과 큐잉으로 180–250ms.
TLS + HTTP 요청이 3–4 RTT면 1초 가까이 간다. 사용자가 버튼을 클릭하고 반응을 볼 때까지 1초 지연. UX 파탄.
CDN은 사용자와 물리적 거리를 줄인다:
- 서울 사용자 → 서울 edge PoP: 5–10ms RTT.
- 원본 서버는 여전히 미국에 있더라도 edge가 대부분 요청 처리.
물리법칙을 이긴 게 아니라 피해간 것이다.
2. CDN의 세 기둥
2.1 라우팅의 삼위일체
사용자를 가장 가까운 edge로 보내는 세 가지 메커니즘:
- Anycast BGP: 같은 IP를 여러 지역이 광고 → BGP가 "가까운" 곳으로 라우팅.
- DNS 기반 라우팅 (GSLB): 사용자 IP의 지역에 따라 다른 edge IP 반환.
- HTTP 기반 리다이렉트: 초기 요청 후 더 가까운 edge로 리다이렉트 (레거시).
주요 CDN은 보통 Anycast + GSLB 혼합.
2.2 Anycast의 장점과 한계
장점:
- DNS 변경 없이 즉시 라우팅 조정.
- BGP 변경 단위로 페일오버 (분 단위).
- 운영 단순.
한계:
- BGP가 "네트워크 거리"만 보지 "서버 부하"는 모름.
- route flap 시 TCP 연결 끊김.
- 지리와 네트워크 경로가 항상 일치하지는 않음 (사우디 요청이 네덜란드로 갈 수 있음).
2.3 GSLB (Global Server Load Balancing)
DNS 기반. Authoritative 서버가 요청자 IP(EDNS Client Subnet이 있으면 더 정확)의 지역에 맞는 edge IP를 반환.
(Tokyo 사용자) → resolver → Authoritative: "www.example.com?"
← Authoritative: "192.0.2.100" (Tokyo PoP)
(London 사용자) → resolver → Authoritative: "www.example.com?"
← Authoritative: "203.0.113.50" (Amsterdam PoP)
장점:
- 서버 부하, 지연, 지역 규제 등 고려한 정교한 결정.
- TCP 연결이 한 edge에 고정 (안정).
한계:
- DNS TTL이 라우팅 변경 속도 제한.
- Resolver 위치와 사용자 위치가 다를 수 있음 (퍼블릭 resolver 사용 시).
2.4 PoP (Point of Presence)
한 지역에 배치된 CDN의 물리적 서버 집합. 일반적 구성:
- Tier-1 ISP 네트워크 내 또는 **IXP (Internet Exchange Point)**에 위치.
- 수십~수백 대 서버.
- 로드 밸런서, edge 서버, 캐시 저장소, 네트워크 장비.
- Tier-1 ISP와 직접 peering → BGP 관점에서 유리한 경로.
Cloudflare는 300+ cities, Akamai는 4,000+ locations. 숫자 차이가 큰 이유:
- Cloudflare: 중요한 IXP 위주의 큰 PoP.
- Akamai: ISP 내부에 깊이 침투한 수많은 작은 "embedded" 서버들.
두 모델의 트레이드오프. 큰 PoP는 유지 쉽고 많은 사이트 커버. 작고 많은 서버는 latency 더 낮지만 운영 복잡.
3. Cache Key — CDN의 근본 결정
3.1 Cache Key의 역할
CDN이 캐시에서 객체를 찾을 때 사용하는 식별자. 올바른 key 설계가 hit rate을 결정한다.
기본 cache key:
scheme + host + path + querystring
예:
https://example.com/images/hero.jpg?w=800
이게 전체 cache key가 된다. 같은 URL을 가진 모든 요청이 같은 캐시 항목에 매핑.
3.2 Vary 헤더 — 복잡성의 시작
Vary 응답 헤더는 "이 응답은 이 요청 헤더에 따라 달라진다"고 CDN에 알린다.
Cache-Control: public, max-age=3600
Vary: Accept-Encoding, Accept-Language
CDN이 cache key를 확장: URL + Accept-Encoding 값 + Accept-Language 값. 같은 URL이지만 gzip과 br이 다른 캐시 항목.
Vary의 함정들:
- Vary: User-Agent: 각 브라우저마다 다른 캐시 → hit rate 파탄. 절대 쓰지 말 것.
- Vary: Cookie: 거의 모든 요청에 다른 쿠키 → 캐시 무용지물.
- 너무 많은 Vary: 조합 폭발로 cache population 어려움.
3.3 Query String 정규화
?utm_source=twitter와 ?utm_source=facebook은 같은 콘텐츠여야 하지만 다른 cache key가 된다. CDN의 "query string normalization" 기능으로 특정 파라미터 무시:
Cloudflare Cache Rules: remove "utm_*" from cache key
Fastly VCL: remove "utm_*" before cache lookup
반대로 중요 파라미터는 명시적 포함:
/search?q=...→q만 cache key에 포함./product?id=...→id포함, tracking 파라미터 제거.
3.4 Cookie와 Personalization
쿠키 있으면 보통 캐시 안 함 (사용자별 다름). 하지만 특정 쿠키만 의미 있으면 다르게:
__logged_in=1유무로 캐시 분리: 익명 사용자에겐 정적 페이지, 로그인 사용자에겐 SSR.- A/B 테스트:
ab_variant=B쿠키로 분리.
CDN의 "Cache by Cookie" 기능. Cloudflare의 "Bypass Cache on Cookie", Fastly VCL의 req.http.Cookie 조작.
3.5 Device Type 기반 분리
Accept-CH: Sec-CH-UA-Mobile 같은 클라이언트 힌트로 모바일/데스크탑 구분. 한 URL이 디바이스별로 다른 HTML 반환 시 필요.
안티패턴: User-Agent 전체를 Vary → cache 폭발. 패턴: 서버가 User-Agent 파싱 후 Vary: X-Device-Type 같은 축소 값으로 변환.
4. HTTP 캐싱 헤더 — 정확한 의미
4.1 Cache-Control
가장 중요한 캐싱 헤더. 디렉티브 조합:
응답 기준:
public: 어떤 캐시든 가능 (브라우저 + CDN).private: 브라우저만 (CDN은 캐시 금지).no-cache: 캐시하되 매번 origin에 유효성 확인.no-store: 절대 캐시 금지.max-age=N: N초 동안 fresh.s-maxage=N: CDN만을 위한 max-age. 브라우저는 무시.immutable: 콘텐츠가 영원히 불변 (폰트, hashed JS 등).stale-while-revalidate=N: 만료 후 N초는 stale을 주면서 백그라운드 갱신.stale-if-error=N: origin 오류 시 N초 동안 stale 반환.
요청 기준:
no-cache: 캐시된 응답 무시하고 origin에서 가져와.only-if-cached: 캐시 없으면 504 반환 (오프라인 모드).
4.2 전형적 패턴들
정적 자산 (hashed filename):
Cache-Control: public, max-age=31536000, immutable
파일명에 해시가 있으므로(app.a3f2b1.js) 변경 시 URL이 바뀜 → 영원히 캐시 안전.
HTML:
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=3600
브라우저 1분, CDN 5분, 그 후 1시간은 stale 허용(갱신은 백그라운드).
API 응답 (공개 데이터):
Cache-Control: public, max-age=10, stale-while-revalidate=60
개인화 응답:
Cache-Control: private, no-cache
브라우저는 캐시 가능하지만 매번 유효성 확인.
민감 데이터:
Cache-Control: no-store
4.3 ETag와 조건부 요청
ETag는 응답의 버전 식별자. 내용이 바뀌면 ETag도 바뀜.
HTTP/1.1 200 OK
ETag: "a3f2b1c4"
Cache-Control: max-age=60
60초 후 브라우저(또는 CDN)가 재요청 시:
GET /page HTTP/1.1
If-None-Match: "a3f2b1c4"
서버가 내용이 바뀌지 않았으면:
HTTP/1.1 304 Not Modified
본문 없이 304만 반환. 대역폭 절약.
Strong vs Weak ETag:
"a3f2b1c4": strong — 바이트 단위 동일.W/"a3f2b1c4": weak — 의미적으로 동일 (예: 응답이 gzip vs br만 다름).
4.4 Last-Modified와 If-Modified-Since
ETag 대안. 파일의 변경 시각 기반.
Last-Modified: Wed, 15 Apr 2026 12:00:00 GMT
If-Modified-Since: Wed, 15 Apr 2026 12:00:00 GMT
시계 문제 있고 해상도가 초라 부정확. 현대 시스템은 ETag 선호.
4.5 stale-while-revalidate — 가장 과소평가된 기능
Cache-Control: max-age=10, stale-while-revalidate=3600
만료 후 1시간 동안은:
- 캐시된 (stale) 응답 즉시 반환.
- 백그라운드에서 origin 갱신 요청.
- 다음 요청부터는 fresh 버전 반환.
사용자 체감은 항상 캐시 속도. Origin 부하는 첫 갱신 요청 하나. SWR (stale-while-revalidate)가 제대로 적용된 서비스는 origin의 트래픽이 놀랍게 적다.
2024년부터 Cloudflare, Fastly, CloudFront 모두 SWR 기본 지원. 2026년 현재는 사용하지 않는 게 이상한 수준.
4.6 Age와 X-Cache 헤더
응답을 받았을 때 CDN이 추가:
Age: 123 # 캐시에 들어간 지 123초
X-Cache: HIT # 캐시 적중
X-Cache-Hits: 5 # 이 객체를 5번 서빙
CF-Cache-Status: HIT # Cloudflare 전용
디버깅의 표준 도구. X-Cache: MISS가 나오면 왜 캐시 안 탔는지 조사.
5. Origin Shield와 Tiered Caching
5.1 일반적 CDN의 위험
Edge PoP 수백 개. 각각이 동일한 origin을 뒤에 둠. 원본 응답이 캐시 만료되면 수백 개 edge가 동시에 origin에 요청 → origin 폭발.
더 나쁜 경우: 핫 콘텐츠 발표 순간 전 세계 edge에서 cold cache → origin DDoS. "Thundering herd" 문제.
5.2 Origin Shield의 개념
Edge와 origin 사이에 단일 중간 캐시 계층 삽입:
User → Edge PoP (전 세계 수백) → Origin Shield PoP (1~몇 개) → Origin
- Edge cache miss → Origin Shield에 요청 (origin 아님).
- Shield cache miss → origin에 요청.
- Shield가 한 번 받아오면 모든 edge가 공유.
효과: origin 부하 10–100배 감소.
5.3 구현 형태
- Cloudflare Tiered Cache / Argo Smart Routing: 각 edge PoP이 "upper tier" 데이터센터로 먼저 조회.
- AWS CloudFront Origin Shield: 특정 region 하나를 shield로 지정.
- Akamai Tiered Distribution: 기본 아키텍처가 이미 다단.
- Fastly Shielding: 쿼리로 어느 PoP을 shield로 쓸지 지정.
5.4 Cache Coalescing (Request Collapsing)
같은 객체에 대한 동시 요청 여럿이 miss면, edge는 한 번만 origin(or shield)에 요청하고 나머지는 기다림.
Nginx의 proxy_cache_lock on, Cloudflare의 자동 request collapsing, Fastly의 request collapsing (기본 활성).
수천 사용자가 동시에 같은 바이럴 콘텐츠를 요청해도 origin 부하는 한 요청.
5.5 Cache Hierarchies의 진화
2020년대 이후 CDN들은 "cache 계층을 더 쌓는" 방향으로 간다:
Browser cache
→ Service Worker cache (PWA)
→ CDN Edge cache
→ CDN Regional cache (mid-tier)
→ Origin Shield
→ Origin
각 계층이 hit ratio 95%+면 origin 실제 부하는 0.001% 수준. 이것이 "99.9% offload" 같은 CDN 마케팅 숫자의 실체.
6. Purge — 캐시 무효화의 기술
6.1 왜 Purge가 어려운가
분산 시스템 필연의 문제: 수백 개 PoP의 캐시를 "동시에" 지울 수 있는가?
- 순차 purge → 수초~수분. 그 사이 어느 사용자는 구 콘텐츠 봄.
- 병렬 purge → 수백 개 요청을 즉시 전파해야 함 → 메시지 버스 필요.
6.2 Purge 전략
URL 기반 (가장 일반적):
POST /api/purge
{ "urls": ["https://example.com/page", "https://example.com/image.jpg"] }
Tag 기반 (surrogate key):
응답에 Surrogate-Key: product-123 category-electronics 추가. purge 시 product-123 태그로 일괄 무효화.
Fastly가 이 기능의 선구자. 상품 하나 업데이트 시 관련 페이지 수백 개 한 번에 purge.
Prefix 기반:
/products/* 같은 패턴. 구현은 CDN마다 다름 (O(N) 스캔이거나 radix tree).
Full site purge: "모두 지워". 비상 수단. origin 폭주의 원인이 되므로 신중히.
6.3 속도 차이
- Cloudflare: 보통 30초 내 전 세계. 태그 기반은 150ms 내.
- Fastly: "Instant Purge" — 150ms 내.
- AWS CloudFront: 수 분 (10–15분). 느리다.
CloudFront의 느린 purge가 아키텍처 선택의 이유가 되곤 한다. Netflix 같은 대형 사용자는 purge보다는 "versioned URLs"로 우회.
6.4 Versioned URLs — Purge 없이 사는 법
<link rel="stylesheet" href="/static/app.v3f2b1a.css">
새 배포 시:
- 새 해시 URL로 파일 빌드.
- HTML만 업데이트 (HTML은 짧은 TTL).
- 기존 캐시된 파일은 자연스레 죽음.
핵심 아이디어: 변경되면 URL이 바뀐다. Purge가 필요 없다. 대부분의 SPA, Next.js, SvelteKit 빌드가 이 방식.
6.5 Soft Purge vs Hard Purge
- Hard Purge: 캐시 즉시 삭제. 다음 요청은 miss.
- Soft Purge: 캐시를 stale로 마크. stale-while-revalidate로 즉시 응답 + 백그라운드 갱신.
Soft purge가 소비자 경험에 훨씬 부드럽다. Fastly가 도입, 이제 대부분 CDN이 지원.
7. Edge Compute — 코드가 edge로 간다
7.1 Edge Compute가 필요한 이유
정적 캐싱만으로 안 되는 것들:
- A/B 테스트의 분기 로직.
- 사용자 인증, JWT 검증.
- 지리 기반 리다이렉트.
- 개인화된 응답.
- API 응답의 경량 변환 (JSON 필드 재배열).
Origin에서 하면 RTT 추가. Edge에서 처리하면 사용자와 가까운 곳에서 즉시.
7.2 Cloudflare Workers — V8 Isolate 모델
2017년 발표. V8 isolate 기반 — 컨테이너/VM 아닌 JS 엔진 수준의 샌드박스.
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === '/hello') {
return new Response('Hello from edge!');
}
// 기본: origin으로 포워딩
return fetch(request);
}
};
- Cold start: 5ms 이하 (컨테이너의 100ms+ 대비).
- 메모리: 128MB per isolate.
- CPU time: 10ms–50ms 기본 한도.
- 분리: 한 worker가 다른 worker 상태 못 봄.
이 가벼움의 비결은 V8 isolate가 프로세스/스레드 생성 없이 격리된 실행 컨텍스트를 만들 수 있는 것. 수만 개 worker가 한 프로세스에서 돌 수 있다.
7.3 Cloudflare Workers의 생태계
- KV: 글로벌 key-value, 최종 일관성. 읽기 빠름, 쓰기 전파 수 초.
- Durable Objects: 단일 인스턴스 stateful. actor 모델.
- D1: SQLite 기반 edge DB.
- R2: S3 호환 object storage. egress 비용 없음.
- Queues: 비동기 메시징.
- Workers Analytics Engine: 시계열 분석.
- AI: LLM 추론 (Llama, Mistral 등).
"backend-as-a-service at edge" — 전통적 서버리스와 구별되는 생태계.
7.4 Fastly Compute@Edge — WebAssembly 모델
2019년 발표. Wasmtime으로 WebAssembly 실행. Rust, AssemblyScript, Go(TinyGo) 지원.
use fastly::http::StatusCode;
use fastly::{Request, Response};
#[fastly::main]
fn main(req: Request) -> Result<Response, Error> {
if req.get_path() == "/hello" {
return Ok(Response::from_status(StatusCode::OK)
.with_body_text_plain("Hello from WASM!"));
}
Ok(req.send("origin_0")?)
}
- Cold start: 50ms 이하.
- 각 요청이 독립 WASM instance → 강한 격리.
- Rust의 성능과 안전성.
7.5 AWS Lambda@Edge vs CloudFront Functions
- Lambda@Edge: 일반 Lambda, Node.js/Python. cold start 있음 (100ms+). viewer request/response, origin request/response 네 지점에서 실행.
- CloudFront Functions: 2021년 발표. V8 기반 초경량. viewer request/response만. 1ms 이하.
Cloudflare Workers의 영향을 받은 CloudFront Functions가 AWS 고객에게 비슷한 경험 제공.
7.6 Vercel Edge Functions — Next.js 통합
Vercel이 Cloudflare Workers 플랫폼 위에 자체 추상. Next.js의 export const runtime = 'edge'로 함수를 edge에서 실행. 프레임워크가 서버리스 경계를 숨긴다.
2024–2026년 Next.js, Astro, Remix, SvelteKit 모두 edge runtime 지원. "어디서 실행되는가"가 프레임워크 문제가 아닌 배포 옵션.
7.7 Edge Compute의 한계
- CPU/메모리 제한: 무거운 계산은 origin으로.
- 파일시스템 없음: 상태는 KV/DB/cache로.
- 장시간 연결 어려움: WebSocket은 지원하지만 connection limits.
- 디버깅 복잡: 글로벌 로그 수집이 필수.
그래서 edge는 "HTTP 경로 변환, 인증, 캐시 결정, 라이트 API"가 주 영역. 무거운 작업은 여전히 origin에.
8. Image/Video 최적화
8.1 왜 이미지가 중요한가
웹 페이지 전송 바이트의 50%+가 이미지. 이미지 최적화 = 페이지 로드 속도 + 대역폭 비용 = UX + 돈.
8.2 포맷 선택
- JPEG: 1992년부터. 여전히 호환성 왕.
- PNG: 무손실. 아이콘, 투명 배경.
- WebP (Google, 2010): JPEG 대비 25–35% 작음.
- AVIF (Alliance for Open Media, 2019): WebP 대비 추가 30% 작음. AV1 코덱 기반.
- JPEG XL (JPEG 그룹, 2021): 고품질 무손실 + 손실 호환. Chrome이 2022년에 잠깐 지원하다 제거, 2024년 다시 실험 플래그.
8.3 Content Negotiation
브라우저가 Accept 헤더로 지원 포맷을 알림:
Accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8
CDN이 이 헤더 기반으로 다른 포맷 반환. <picture> 요소 없이 한 URL로 최적 포맷.
Cloudflare Polish, Fastly Image Optimizer, CloudFront (Lambda@Edge 통해), Imgix, Cloudinary 등이 이 기능 제공.
8.4 Responsive Images
디스플레이 크기별로 다른 이미지:
<img src="hero.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, 50vw">
CDN이 srcset의 각 URL을 알아서 생성:
https://cdn.example.com/hero.jpg?width=400&format=auto
https://cdn.example.com/hero.jpg?width=800&format=auto
format=auto가 accept 헤더 기반 최적 포맷. 각 URL이 별도 cache key로 저장.
8.5 Video — HLS와 DASH
스트리밍의 실제는 HTTP 기반 적응형 스트리밍:
- HLS (HTTP Live Streaming, Apple):
.m3u8playlist +.ts세그먼트. - MPEG-DASH:
.mpdmanifest + 세그먼트. - CMAF (Common Media Application Format): HLS/DASH 공통 포맷.
서버가 비디오를 여러 해상도 × 여러 비트레이트로 인코딩 → 작은 세그먼트(2–10초)로 쪼갬 → 각 세그먼트가 개별 HTTP GET으로 다운. 네트워크 상태에 따라 세그먼트별로 품질 조정.
CDN에게는 수많은 작은 정적 파일의 집합. 캐싱이 매우 잘 됨. Netflix, YouTube, Twitch가 이 모델로 스케일.
8.6 Perceptual Quality Metrics
"얼마나 압축할 것인가"의 결정. 파일 크기 vs 시각 품질.
- PSNR: 고전. 픽셀 차이 기반. 사람 지각과 안 맞음.
- SSIM: 구조적 유사도. PSNR보다 나음.
- VMAF (Netflix, 2016): 머신러닝으로 실제 사람 평가 예측. 업계 표준이 됨.
Netflix는 같은 콘텐츠를 수백 가지 인코딩 조합으로 만들어 VMAF 높은 것만 선택. 대역폭 20% 절감.
9. TLS Termination과 보안
9.1 TLS Termination at Edge
사용자 ↔ edge 사이 TLS 종료. edge ↔ origin 사이는 별도 TLS (또는 사설망).
User --TLS 1.3 (X25519)--> Edge --TLS (mutual auth)--> Origin
장점:
- 인증서 관리 중앙화.
- 최신 TLS/QUIC을 edge에서 즉시 배포.
- TLS 핸드셰이크를 사용자 가까이에서 → RTT 감소.
9.2 Universal SSL (Cloudflare 2014)
Cloudflare가 "모든 고객에게 무료 SSL" 발표. SNI를 활용해 한 IP에 수천 도메인 호스팅. Let's Encrypt 이전 시대의 혁명.
지금은 HTTP/3, ECH까지 edge에서 자동 적용.
9.3 Origin 보호
Edge가 있어도 origin이 공개돼 있으면 공격자가 edge를 우회. 방어:
- Authenticated Origin Pulls: origin이 CDN의 client cert만 허용.
- IP 제한: CDN의 IP 범위만 origin이 accept.
- Origin 숨기기: origin DNS 이름 공개 안 함.
- Cloudflare Tunnel 같은 reverse tunnel: origin이 outbound 연결만.
9.4 DDoS 흡수
CDN의 대역폭 용량은 수 Tbps 규모. 작은 origin 서버(수 Gbps)보다 1000배 많음. 공격 트래픽을 edge가 흡수 → origin 보호.
주요 CDN의 공격 완화 능력:
- Cloudflare: 228 Tbps 글로벌 용량 (2025년 수치).
- Akamai: 비슷한 규모.
- AWS Shield Advanced: AWS 계정 보호.
알려진 최대 공격 (2023 공식 기록): 398 Tbps HTTP/2 Rapid Reset. Cloudflare/Google/AWS가 동시 완화.
9.5 Bot 관리
트래픽의 30–50%가 봇이라는 통계. 일부는 합법(Googlebot, Bingbot), 대부분은 악성(스크래퍼, credential stuffing).
CDN의 bot 관리:
- Fingerprinting: TLS/HTTP2 fingerprint, JA3 해시.
- Challenge: JS challenge, CAPTCHA, Cloudflare Turnstile.
- Behavioral: 마우스 움직임, 클릭 패턴 분석.
- ML classification: 수백 개 시그널로 bot score.
Cloudflare Bot Management, Akamai Bot Manager, Fastly Bot Management가 이 시장. 전통 CAPTCHA는 접근성 문제로 밀려나는 중.
9.6 WAF (Web Application Firewall)
SQL injection, XSS, RCE 등을 edge에서 차단.
- 규칙 기반: OWASP Core Rule Set (CRS)이 표준.
- 커스텀 규칙: 자사 API 패턴 보호.
- 머신러닝: 이상치 탐지, novel attack 탐지.
클라우드 WAF: Cloudflare WAF, AWS WAF, Akamai AppSec. 전통 on-prem WAF (F5, Imperva)의 대체재.
10. 대역폭 경제학
10.1 Egress 비용의 진실
AWS S3, GCS, Azure Blob이 egress 비용을 청구: 데이터를 "밖으로" 내보낼 때. 안으로(ingress)는 공짜.
2024년 AWS 요금(변동):
- 100TB/월까지: $0.09/GB → 월 9,000달러.
- 1PB/월: ~$0.05/GB 할인 → 월 50,000달러.
웹사이트가 100TB 트래픽이면 CDN 없이 AWS 비용만 월 1,000만 원.
10.2 CDN의 경제학
CDN 요금은 보통 AWS egress의 1/3–1/5:
- Cloudflare: 무료 플랜 있음, 유료는 약 $0.02/GB.
- Fastly: $0.12/GB (비싸지만 성능/기능).
- CloudFront: $0.085/GB.
- Bunny.net: $0.01/GB (저렴형).
그리고 CDN이 대부분을 cache에서 서빙 → origin egress 99%+ 감소. AWS egress + CDN 비용 < AWS egress만.
10.3 R2, B2, Cloudflare R2 — "Zero Egress"
Cloudflare R2, Backblaze B2 가 egress 무료. AWS S3의 egress 청구 모델에 대한 반격.
R2: S3 호환 API, egress 0.015/GB (S3보다 저렴). Cloudflare가 이 모델을 유지할 수 있는 이유 — Cloudflare 네트워크 자체의 트래픽은 이미 sunk cost.
Bandwidth Alliance: Cloudflare + Backblaze + DigitalOcean + Wasabi 등이 서로 간 egress 무료/할인. 멀티클라우드의 경제적 동력.
10.4 P2P와 Peer-Assisted CDN
Netflix의 Open Connect: ISP 내부에 서버 배치 → 해당 ISP 사용자는 ISP 내부에서 영상 받음. ISP도 대외 대역폭 절약 → ISP가 환영.
P2P 방식: 다른 사용자의 브라우저를 peer로 활용. WebTorrent, Peer5 등. 라이센스/프라이버시 이슈로 제한적.
10.5 Cache Hit Ratio의 경제학
95% hit ratio → 5%만 origin 부담. 99% hit ratio → 1%만 origin 부담.
4 percentage points 차이가 origin 비용을 5배 절감. cache key, TTL, purge 전략의 ROI가 거대하다.
11. 실전 설정
11.1 Cache-Control 정책 템플릿
# 정적 자산 (hashed)
Cache-Control: public, max-age=31536000, immutable
# HTML
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=86400
# 공개 API
Cache-Control: public, max-age=10, s-maxage=60, stale-while-revalidate=300
# 개인화 (로그인 사용자)
Cache-Control: private, max-age=0, must-revalidate
# 비공개 민감 데이터
Cache-Control: no-store
11.2 Cloudflare Page Rules (또는 Cache Rules)
# /static/* — 오래 캐시
Match: (http.request.uri.path matches "^/static/")
Action: Cache Level = Cache Everything
Edge Cache TTL = 1 year
Browser Cache TTL = 1 year
# /api/* — 캐시 안 함
Match: (http.request.uri.path matches "^/api/")
Action: Cache Level = Bypass
# 쿠키로 분기
Match: (http.cookie contains "logged_in=1")
Action: Cache Level = Bypass
11.3 Fastly VCL 예
sub vcl_recv {
# uppercase 경로 정규화
set req.url = std.tolower(req.url);
# tracking 파라미터 제거
set req.url = regsuball(req.url, "(utm_[^&=]+|fbclid|gclid)=[^&]+&?", "");
set req.url = regsub(req.url, "[?&]$", "");
# 로그인 쿠키 있으면 캐시 bypass
if (req.http.Cookie ~ "session=") {
return(pass);
}
}
sub vcl_fetch {
# SWR 추가
if (beresp.http.Cache-Control !~ "stale-while-revalidate") {
set beresp.http.Cache-Control = beresp.http.Cache-Control + ", stale-while-revalidate=3600";
}
}
11.4 Next.js의 edge 최적화
// next.config.js
module.exports = {
async headers() {
return [
{
source: '/_next/static/:path*',
headers: [{ key: 'Cache-Control', value: 'public, max-age=31536000, immutable' }]
},
{
source: '/',
headers: [{ key: 'Cache-Control', value: 'public, max-age=0, s-maxage=300, stale-while-revalidate=86400' }]
}
];
}
};
Vercel에 배포하면 자동으로 edge 네트워크로 배포 → 전 세계 사용자에게 빠름.
11.5 모니터링 지표
- Cache hit ratio: >90% 목표. 낮으면 cache key/TTL 재검토.
- Origin RPS: 갑자기 치솟으면 purge/배포 이슈 의심.
- p99 latency from edge: 지역별.
- Bandwidth egress: origin과 edge 각각.
- 5xx rate: origin vs edge.
Cloudflare Analytics, Fastly Observability, CloudFront CloudWatch 등 기본 제공.
11.6 안티패턴
- Cache-Control 안 설정: 브라우저 기본(heuristic)에 맡김 → 일관성 없음. 반드시 명시.
- Vary: User-Agent: 캐시 폭발. 절대 금지.
- 쿠키 의존 페이지를 캐시: 사용자별 다른 내용이 잘못된 사용자에게 보임. 데이터 유출.
- PII를 쿼리 스트링에: 캐시 키로 들어가 로그/분석에 노출.
- Purge 남용: 변경마다 전면 purge → origin 폭주.
- Origin의 Cache-Control 무시: CDN이 강제 override하면 앱 의도와 어긋남.
12. 최신 트렌드
12.1 HTTP/3 at Edge
Cloudflare, Fastly, CloudFront 모두 HTTP/3 기본 지원. 모바일 사용자에게 특히 효과 — connection migration으로 Wi-Fi ↔ 셀룰러 전환 중에도 끊김 없음.
12.2 Streaming SSR
React Server Components, Next.js App Router의 streaming은 edge와 찰떡. 첫 바이트(TTFB) 수 ms, HTML이 도착하는 대로 점진적 렌더링.
12.3 Edge AI
Cloudflare Workers AI, Fastly AI Accelerator: LLM 추론을 edge에서. 사용자 가까이에서 토큰 생성 → 첫 토큰 지연 대폭 감소.
GPU를 모든 edge PoP에 배치 못 함 → 주요 PoP에 GPU, 나머지는 가까운 GPU PoP으로 라우팅. Edge AI와 Edge Compute의 hybrid.
12.4 Zero Trust Networking
CDN이 확장된 기업 네트워크 되기. Cloudflare Zero Trust (Cloudflare One), Akamai Zero Trust, Zscaler. VPN 대체.
"edge가 모든 트래픽의 관문" 비전. 개인 사용자 → edge → 사내 리소스. identity 기반 접근 제어.
12.5 WebAssembly Components
WASM의 새 인터페이스 표준(Component Model). 언어 간 상호운용 + 안전한 샌드박스. Fastly Compute@Edge가 선도. 여러 언어로 작성된 미들웨어를 조합.
13. 깊이 들어간 운영자를 위한 팁
13.1 Cache 디버깅 루틴
# 응답 헤더 확인
curl -I https://example.com/page
# Cloudflare 디버깅
curl -I https://example.com/page \
-H "X-Cloudflare-Debug: 1"
# 다른 지역에서 테스트 (cloudflare-radar, fastly-network-info)
CF-Cache-Status, X-Cache, Age 헤더를 확인하라. MISS 반복이면 cache key 재검토.
13.2 Cache warming
배포 후 또는 새 지역 추가 시 주요 URL 목록에 미리 요청 → cache populate.
while read url; do
for region in US EU APAC; do
curl -H "X-Test-Region: $region" "$url" > /dev/null &
done
done < critical-urls.txt
13.3 A/B 테스트를 edge에서
// Cloudflare Worker 예시
export default {
async fetch(req) {
const cookie = req.headers.get('Cookie') || '';
let variant = cookie.match(/exp=(\w)/)?.[1];
if (!variant) {
variant = Math.random() < 0.5 ? 'A' : 'B';
}
const url = new URL(req.url);
if (variant === 'B') url.pathname = '/v2' + url.pathname;
const resp = await fetch(url, req);
const newResp = new Response(resp.body, resp);
newResp.headers.append('Set-Cookie', `exp=${variant}; Max-Age=2592000`);
return newResp;
}
};
Origin이 모르는 사이 variant 분기. 각 사용자는 쿠키 기반으로 고정 variant 유지.
13.4 Incident 대응
"갑자기 트래픽이 origin에 몰려요":
- CDN dashboard의 cache hit ratio 확인. 급락했나?
- 최근 purge 이벤트 로그 확인.
- Cache-Control 헤더 설정이 바뀌지 않았나.
- 5xx 응답이 증가했나 (5xx는 캐시 안 됨, origin에 반복 요청).
- Vary 헤더에 새 값이 추가됐나.
대응:
- 임시로 origin shield 활성.
- CDN 설정에서
Edge Cache TTL강제 (origin 무시). - WAF rule로 abuse 패턴 차단.
13.5 "Cache Poisoning" 조심
공격자가 요청 헤더 조작 → 서버가 오염된 응답 생성 → CDN 캐시 → 모든 사용자가 감염.
예: X-Forwarded-Host: attacker.com → 앱이 이를 링크에 사용 → 캐시.
방어: 의심스러운 헤더 제거(unset), cache key에 신뢰할 수 있는 헤더만 포함, canonicalization.
James Kettle의 2018 DEF CON 발표 "Practical Web Cache Poisoning"이 이 분야의 고전.
맺음 — 바이트를 사용자 옆으로
CDN의 본질은 간단하다: 바이트를 사용자 옆에 두라. 그리고 그 간단한 원리가 현대 웹의 속도와 경제성을 가능하게 한다.
운영자로서 본능적으로 체크할 세 가지:
- Cache hit ratio를 측정하라. 90% 이상이 기본. 낮으면 설정 문제.
- Cache-Control 헤더를 의도적으로 써라. 기본값 의존은 재앙. SWR은 반드시 추가.
- Origin shield/tiered cache를 활용하라. 무료/저비용인데 origin 부하 10배 감소.
이 세 가지만 제대로면 CDN이 약속한 속도와 절감의 90%를 얻는다.
더 넓게 보면, 지난 세 글은 웹 요청의 여정을 라우팅부터 응답까지 추적했다:
- DNS: 이름 해결.
- TLS 1.3 + QUIC: 안전한 채널 수립.
- CDN (이 글): 바이트의 실제 전달.
HTTPS 요청 한 번을 1 ms부터 100 ms까지 바이트 단위로 설명할 수 있는 엔지니어는 장애 대응에서 30초 안에 원인을 짚어낸다.
다음 글은 Git 내부 구조 — 객체 모델, 참조, 팩 파일, rebase의 실제 동작을 다룬다. 매일 쓰지만 거의 아무도 내부를 모르는 도구. 바이트 수준에서 풀어낸다.
CDN Complete Guide — Cache, Edge Compute, Origin Shield, and HTTP Caching Headers (2025)
Intro — 99% of the Web You See Comes From the Edge
In 2026, when you hit any major website, almost every byte you receive arrives from an edge server, not the origin. Cloudflare runs in 300+ cities, Akamai in 4,000+ locations, Fastly in dozens of major PoPs. These edges cache HTML, images, JS, video, apply rules in real time, terminate TLS, and absorb DDoS.
Without this layer, the modern web is impossible. Netflix streams 1EB per day without melting origins because of edge. A news site surviving a viral article, shoppers hitting a site on Black Friday at 1000x normal load, global users getting similar latency — all of it depends on edge caching.
This post follows naturally from the DNS deep dive. Once DNS routes a user to an edge PoP, we trace what happens at the byte level.
1. A Short History of the CDN
1.1 The Birth of Akamai
In 1995, MIT math professor Tom Leighton and PhD student Danny Lewin asked: how do we distribute web content globally at speed? Their insight was mathematical — use consistent hashing to spread content across many servers and route users to the nearest one.
Akamai Technologies launched in 1998. In 1999 a Super Bowl site went down and Akamai absorbed the traffic, putting the CDN concept on the industry map.
During 9/11 in 2001, major news sites survived thanks to Akamai. CNN, ESPN, and Fox News standardized on it afterward.
1.2 New Generations
- Mid-2000s: CloudFront, Limelight, EdgeCast emerge.
- 2010: Cloudflare founded, bundling DDoS protection and CDN on a free plan.
- 2011: Fastly founded with "Instant Purge" — cache invalidation within 150ms worldwide.
- 2017: Cloudflare Workers announced, powered by V8 Isolates.
- 2019: Fastly Compute@Edge, WebAssembly and Rust based.
- 2020–2024: Netflix, AWS, Meta increasingly build their own CDNs.
Major 2026 players: Cloudflare (leader, developer-friendly), Akamai (enterprise, security), Fastly (performance), Amazon CloudFront, Google Cloud CDN, Azure CDN, Bunny.net, KeyCDN.
1.3 Why CDN (The Math of Latency)
Light travels 300,000 km/s, roughly 2/3 of that through fiber. Seoul to New York is 11,000 km one way — minimum 55ms one-way, 110ms RTT. Real-world routing and queueing push it to 180–250ms.
A TLS and HTTP exchange of 3–4 RTTs approaches one second. From click to response, that is a UX disaster.
The CDN shortens physical distance: a Seoul user hitting a Seoul edge sees 5–10ms RTT even if the true origin is in the US. You do not beat physics, you sidestep it.
2. The Three Pillars of a CDN
2.1 Routing Trinity
Three mechanisms route users to the nearest edge:
- Anycast BGP: the same IP is advertised from many regions; BGP picks the "nearest."
- DNS-based routing (GSLB): the authoritative server returns a region-appropriate IP.
- HTTP redirects: legacy fallback.
Most major CDNs combine Anycast and GSLB.
2.2 Anycast — Pros and Cons
Pros: no DNS changes needed, BGP-speed failover, simple ops. Cons: BGP sees network distance, not server load; route flaps drop TCP connections; geography and network path do not always align (a Saudi request can land in the Netherlands).
2.3 GSLB
DNS-based. The authoritative server returns an edge IP matching the requester's region (more accurate with EDNS Client Subnet).
(Tokyo user) -> resolver -> Authoritative "www.example.com?"
<- Authoritative "192.0.2.100" (Tokyo PoP)
(London user) -> resolver -> Authoritative "www.example.com?"
<- Authoritative "203.0.113.50" (Amsterdam PoP)
Pros: considers load, latency, regulation. TCP connection stays pinned to one edge. Cons: DNS TTL bounds routing change speed; public resolver locations may differ from users.
2.4 PoP (Point of Presence)
A physical cluster of CDN servers in one region. Typically located inside a Tier-1 ISP or at an IXP. Dozens to hundreds of servers, load balancers, edge nodes, cache storage. Direct peering with Tier-1 ISPs yields better BGP paths.
Cloudflare has 300+ cities, Akamai 4,000+ locations. The gap is strategy: Cloudflare favors large PoPs at key IXPs; Akamai embeds many small servers deep inside ISPs.
3. Cache Key — The Fundamental Decision
3.1 The Role
The cache key identifies objects in the cache. Correct design determines hit rate.
Default:
scheme + host + path + querystring
Example: https://example.com/images/hero.jpg?w=800 becomes the whole cache key.
3.2 The Vary Header — Where Complexity Begins
The Vary response header tells the CDN "this response varies based on these request headers."
Cache-Control: public, max-age=3600
Vary: Accept-Encoding, Accept-Language
The CDN extends the key to URL + Accept-Encoding + Accept-Language. Same URL, different entries for gzip vs br.
Vary traps:
Vary: User-Agent— per-browser cache, destroys hit rate. Never.Vary: Cookie— almost every request has unique cookies. Cache useless.- Too many Vary values — combinatorial explosion.
3.3 Query String Normalization
?utm_source=twitter and ?utm_source=facebook serve identical content but become different keys. Use the CDN's normalization to strip utm_* before cache lookup (Cloudflare Cache Rules, Fastly VCL).
3.4 Cookies and Personalization
With cookies, default to bypassing cache. When a specific cookie matters, split explicitly: cache anon users statically, cache logged-in with SSR. A/B tests can use a ab_variant cookie.
3.5 Device Type Splitting
Use Client Hints like Sec-CH-UA-Mobile. Do not Vary on the whole User-Agent — parse at origin and translate into a narrow header like X-Device-Type.
4. HTTP Caching Headers — Precise Semantics
4.1 Cache-Control
Most important header. Key directives:
public/private: any cache vs browser only.no-cache: cache but always revalidate.no-store: never cache.max-age=N: fresh for N seconds.s-maxage=N: CDN-only max-age.immutable: content never changes (fonts, hashed JS).stale-while-revalidate=N: serve stale for N seconds while refreshing in background.stale-if-error=N: serve stale on origin error.
4.2 Typical Patterns
Static assets with hashed filename:
Cache-Control: public, max-age=31536000, immutable
HTML:
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=3600
Public API:
Cache-Control: public, max-age=10, stale-while-revalidate=60
Personalized: Cache-Control: private, no-cache. Sensitive: Cache-Control: no-store.
4.3 ETag and Conditional Requests
An ETag identifies a response version. Browser or CDN revalidates with If-None-Match: "a3f2b1c4". If unchanged, the server returns 304 Not Modified without a body.
Strong ETag ("abc") means byte-identical; weak (W/"abc") means semantically equivalent.
4.4 Last-Modified / If-Modified-Since
Time-based alternative. Second resolution, clock issues — modern systems prefer ETag.
4.5 stale-while-revalidate — Most Underrated
Cache-Control: max-age=10, stale-while-revalidate=3600
After expiry, for 1 hour: (1) serve cached stale immediately, (2) fetch from origin in background, (3) subsequent requests get fresh. Users always experience cache speed; origin gets one refresh. Supported on Cloudflare, Fastly, CloudFront.
4.6 Age and X-Cache
CDN adds: Age: 123, X-Cache: HIT, X-Cache-Hits: 5, CF-Cache-Status: HIT. Standard debugging tools.
5. Origin Shield and Tiered Caching
5.1 The Problem
Hundreds of edge PoPs fronting the same origin. When a popular object expires, hundreds of edges hit origin at once — origin explodes. Thundering herd.
5.2 Origin Shield
Insert a single intermediate layer:
User -> Edge PoPs (hundreds) -> Origin Shield PoP (1 or few) -> Origin
Edge miss queries Shield; Shield miss queries origin. Origin load drops 10–100x.
5.3 Implementations
- Cloudflare Tiered Cache / Argo Smart Routing.
- AWS CloudFront Origin Shield (designate a region).
- Akamai Tiered Distribution (native to architecture).
- Fastly Shielding (choose a PoP per query).
5.4 Cache Coalescing
When many concurrent requests miss the same object, edge fetches once and waits the rest. Nginx proxy_cache_lock, Cloudflare automatic, Fastly default. Thousands of viral-content viewers result in a single origin request.
5.5 Hierarchy Evolution
Browser cache
-> Service Worker cache
-> CDN Edge cache
-> CDN Regional cache
-> Origin Shield
-> Origin
With each layer at 95%+ hit ratio, origin sees 0.001% of traffic. That is the real number behind "99.9% offload" marketing.
6. Purge — The Art of Invalidation
6.1 Why Purge Is Hard
Invalidating caches across hundreds of PoPs simultaneously requires a global message bus. Sequential purge leaves stale content in some regions for seconds to minutes.
6.2 Strategies
- By URL: most common.
- By tag (surrogate key): response carries
Surrogate-Key: product-123; purge by tag invalidates hundreds of related pages. Fastly pioneered this. - By prefix:
/products/*style. - Full purge: emergency only.
6.3 Speed
Cloudflare: ~30s globally, 150ms by tag. Fastly: 150ms. CloudFront: 10–15 minutes — slow enough to shape architecture.
6.4 Versioned URLs
<link rel="stylesheet" href="/static/app.v3f2b1a.css">
New deploy: new hash, update HTML only (short TTL). Old cached files die naturally. Most SPAs, Next.js, SvelteKit use this. If URL changes, no purge needed.
6.5 Soft vs Hard Purge
Soft purge marks entries stale and uses SWR for immediate response plus background refresh. Much smoother UX. Fastly introduced it; most CDNs now support.
7. Edge Compute — Code Moves to the Edge
7.1 Why
Static caching cannot handle A/B branching, auth, geo redirects, personalization, light API transforms. Doing those at origin adds RTT. Doing them at edge keeps latency low.
7.2 Cloudflare Workers — V8 Isolate Model
Announced 2017. V8 isolates — not containers or VMs, but JS-engine-level sandboxes.
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === '/hello') {
return new Response('Hello from edge!');
}
return fetch(request);
}
};
Cold start under 5ms vs 100ms+ for containers. 128MB per isolate, 10–50ms CPU. Thousands of workers in one process.
7.3 Workers Ecosystem
- KV: global key-value, eventual consistency.
- Durable Objects: single-instance stateful actors.
- D1: SQLite edge DB.
- R2: S3-compatible object storage, no egress fees.
- Queues, Analytics Engine, Workers AI (LLM inference).
Backend-as-a-service at edge.
7.4 Fastly Compute@Edge — WebAssembly
2019, Wasmtime running WebAssembly. Rust, AssemblyScript, TinyGo.
use fastly::http::StatusCode;
use fastly::{Request, Response};
#[fastly::main]
fn main(req: Request) -> Result<Response, Error> {
if req.get_path() == "/hello" {
return Ok(Response::from_status(StatusCode::OK)
.with_body_text_plain("Hello from WASM!"));
}
Ok(req.send("origin_0")?)
}
Cold start under 50ms. Each request gets an independent WASM instance.
7.5 AWS Lambda@Edge vs CloudFront Functions
Lambda@Edge: full Lambda, Node.js or Python, 100ms+ cold start, four execution points. CloudFront Functions: 2021, V8-based, sub-1ms, viewer-only. AWS answer to Workers.
7.6 Vercel Edge Functions
Vercel abstracts on top of Cloudflare Workers. Next.js export const runtime = 'edge' runs on edge. By 2026 Next.js, Astro, Remix, SvelteKit all support edge runtimes.
7.7 Limits
CPU and memory limits, no filesystem, limited long-lived connections, harder debugging. Heavy work still belongs at origin.
8. Image and Video Optimization
8.1 Why Images Matter
Over 50% of page bytes are images. Optimization equals UX plus money.
8.2 Formats
- JPEG: universal fallback.
- PNG: lossless, transparency.
- WebP (2010): 25–35% smaller than JPEG.
- AVIF (2019): 30% smaller than WebP.
- JPEG XL: high-quality lossless, Chrome flag experiment.
8.3 Content Negotiation
Browser sends Accept: image/avif,image/webp,.... CDN returns best supported format under one URL. Cloudflare Polish, Fastly Image Optimizer, Imgix, Cloudinary.
8.4 Responsive Images
<img src="hero.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, 50vw">
CDN generates each variant on demand with ?width=800&format=auto. Each URL is a separate cache key.
8.5 Video — HLS and DASH
HTTP-based adaptive streaming. HLS (Apple) uses .m3u8 plus .ts; DASH uses .mpd; CMAF unifies. Video encoded in multiple resolutions and bitrates, chopped into 2–10s segments. From the CDN view these are many small static files, extremely cache-friendly.
8.6 Perceptual Metrics
PSNR (outdated), SSIM, VMAF (Netflix, 2016) — ML-predicted human judgment, industry standard. Netflix encodes each title in hundreds of combinations and picks top VMAF, saving 20% bandwidth.
9. TLS Termination and Security
9.1 TLS at Edge
User to edge TLS, edge to origin another TLS (or private). Centralized cert management, fast rollout of TLS/QUIC, shorter handshake RTT.
9.2 Universal SSL (Cloudflare, 2014)
Free SSL for all customers via SNI. Revolutionary pre-Let's Encrypt. Now extended to HTTP/3, ECH.
9.3 Protecting the Origin
An exposed origin defeats the edge. Defenses: Authenticated Origin Pulls (mutual TLS), IP allowlists for CDN ranges, hiding origin DNS, Cloudflare Tunnel (outbound-only origin).
9.4 DDoS Absorption
CDN has Tbps capacity; small origins have Gbps. Edge absorbs attack. Cloudflare advertises 228 Tbps (2025). Largest documented attack: 398 Tbps HTTP/2 Rapid Reset (2023), mitigated by Cloudflare, Google, AWS.
9.5 Bot Management
30–50% of traffic is bots. Legit (Googlebot) vs malicious (scrapers, credential stuffing). CDN tooling: TLS/HTTP2 fingerprints (JA3), JS challenges, Turnstile, behavioral, ML bot scoring.
9.6 WAF
SQL injection, XSS, RCE blocked at edge. OWASP CRS as baseline, custom rules, ML for anomalies. Cloudflare WAF, AWS WAF, Akamai AppSec replacing F5 and Imperva on-prem.
10. Bandwidth Economics
10.1 Egress Truth
AWS S3, GCS, Azure Blob bill egress (outbound). 2024 AWS: 9,000.
10.2 CDN Math
CDN is typically 1/3 to 1/5 of AWS egress: Cloudflare ~0.12/GB, CloudFront 0.01/GB. Combined with high hit ratio, origin egress drops 99%+.
10.3 R2, B2 — Zero Egress
Cloudflare R2 and Backblaze B2 offer zero egress. R2: S3-compatible, 0.015/GB storage. Bandwidth Alliance (Cloudflare, Backblaze, DigitalOcean, Wasabi) cross-egress free.
10.4 Peer-Assisted
Netflix Open Connect places boxes inside ISPs; ISP users get video from inside the ISP, saving ISP transit. P2P via WebTorrent or Peer5 is niche due to licensing.
10.5 Hit Ratio Economics
95% to 99% hit ratio cuts origin cost 5x. Key design, TTL, and purge strategy have enormous ROI.
11. Practical Configuration
11.1 Cache-Control Templates
# Hashed static
Cache-Control: public, max-age=31536000, immutable
# HTML
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=86400
# Public API
Cache-Control: public, max-age=10, s-maxage=60, stale-while-revalidate=300
# Personalized
Cache-Control: private, max-age=0, must-revalidate
# Sensitive
Cache-Control: no-store
11.2 Cloudflare Cache Rules
# /static/* long cache
Match: (http.request.uri.path matches "^/static/")
Action: Cache Everything, Edge TTL 1y, Browser TTL 1y
# /api/* bypass
Match: (http.request.uri.path matches "^/api/")
Action: Bypass
# bypass on login cookie
Match: (http.cookie contains "logged_in=1")
Action: Bypass
11.3 Fastly VCL
sub vcl_recv {
set req.url = std.tolower(req.url);
set req.url = regsuball(req.url, "(utm_[^&=]+|fbclid|gclid)=[^&]+&?", "");
set req.url = regsub(req.url, "[?&]$", "");
if (req.http.Cookie ~ "session=") {
return(pass);
}
}
sub vcl_fetch {
if (beresp.http.Cache-Control !~ "stale-while-revalidate") {
set beresp.http.Cache-Control = beresp.http.Cache-Control + ", stale-while-revalidate=3600";
}
}
11.4 Next.js Edge Optimization
module.exports = {
async headers() {
return [
{
source: '/_next/static/:path*',
headers: [{ key: 'Cache-Control', value: 'public, max-age=31536000, immutable' }]
},
{
source: '/',
headers: [{ key: 'Cache-Control', value: 'public, max-age=0, s-maxage=300, stale-while-revalidate=86400' }]
}
];
}
};
11.5 Metrics
Cache hit ratio target above 90%. Watch origin RPS, p99 latency by region, egress bytes, 5xx rate.
11.6 Anti-Patterns
- No Cache-Control set, relying on heuristics.
Vary: User-Agent.- Caching cookie-dependent pages — data leaks.
- PII in query strings.
- Abusive global purge.
- CDN overriding origin Cache-Control silently.
12. Trends
12.1 HTTP/3 at Edge
Default on Cloudflare, Fastly, CloudFront. Connection migration benefits mobile users switching Wi-Fi and cellular.
12.2 Streaming SSR
React Server Components and Next.js App Router streaming fit edge beautifully: sub-ms TTFB, progressive HTML.
12.3 Edge AI
Cloudflare Workers AI, Fastly AI Accelerator run LLM inference near users. GPUs in major PoPs, nearest-GPU routing from the rest.
12.4 Zero Trust
Cloudflare One, Akamai Zero Trust, Zscaler — CDN edge becomes corporate network gateway, replacing VPN with identity-based access.
12.5 WebAssembly Components
Component Model enables safe multi-language composition. Fastly Compute@Edge leads.
13. Operator Tips
13.1 Debugging
curl -I https://example.com/page
curl -I https://example.com/page -H "X-Cloudflare-Debug: 1"
Check CF-Cache-Status, X-Cache, Age. Repeated MISS means revisit cache key.
13.2 Warming
After deploy or new region, pre-request critical URLs:
while read url; do
for region in US EU APAC; do
curl -H "X-Test-Region: $region" "$url" > /dev/null &
done
done < critical-urls.txt
13.3 A/B at Edge
export default {
async fetch(req) {
const cookie = req.headers.get('Cookie') || '';
let variant = cookie.match(/exp=(\w)/)?.[1];
if (!variant) {
variant = Math.random() < 0.5 ? 'A' : 'B';
}
const url = new URL(req.url);
if (variant === 'B') url.pathname = '/v2' + url.pathname;
const resp = await fetch(url, req);
const newResp = new Response(resp.body, resp);
newResp.headers.append('Set-Cookie', `exp=${variant}; Max-Age=2592000`);
return newResp;
}
};
Origin stays oblivious; per-user variant stays sticky via cookie.
13.4 Incident Triage
"Origin suddenly seeing huge traffic": check hit ratio drop, recent purges, Cache-Control changes, 5xx spike (uncached), new Vary values. Temporary response: enable Origin Shield, force Edge TTL, WAF rules.
13.5 Cache Poisoning
Attacker manipulates headers; origin produces poisoned response; CDN caches; everyone gets infected. Example: X-Forwarded-Host: attacker.com ending up in generated links. Defenses: strip suspicious headers, keep cache key to trusted inputs, canonicalize. James Kettle's 2018 DEF CON talk is the classic reference.
Closing — Bytes Next to Users
The essence of a CDN is simple: keep bytes next to users. That simple rule powers the speed and economics of the modern web.
Three operator reflexes:
- Measure cache hit ratio. 90%+ baseline.
- Set Cache-Control deliberately. Always add SWR.
- Use Origin Shield / tiered cache. Free wins.
Three recent posts trace a request from routing to response:
- DNS: name resolution.
- TLS 1.3 + QUIC: secure channel.
- CDN (this post): the actual delivery.
Next up: Git internals — object model, refs, packfiles, rebase under the hood.