Skip to content
Published on

CDN 完全ガイド — Cache、Edge Compute、Origin Shield、HTTP Caching ヘッダーのすべて (2025)

Authors

はじめに — あなたが見る Web の 99% は Edge から来る

2026 年現在、主要な Web サイトにアクセスすると、受け取るバイトのほぼ全てが origin ではなく edge サーバ から届く。Cloudflare は世界 300 以上の都市、Akamai は 4,000 以上の拠点、Fastly は数十の主要 PoP にサーバを置く。これらの edge が HTML、画像、JS、動画をキャッシュし、リアルタイムでルールを適用し、TLS を終端し、DDoS を吸収する。

この層なしでは現代の Web は成立しない。Netflix が 1 日 1EB をストリーミングしながら origin を守れる理由、ショッピングサイトがブラックフライデーに 1000 倍のトラフィックに耐える理由、世界のユーザが似た latency で Web を使える理由 — すべて CDN の edge caching に由来する。

本記事は DNS 記事の自然な続編であり、DNS がユーザを edge PoP にルーティングした後に何が起こるかをバイト単位で描く。


1. CDN の短い歴史

1.1 Akamai の誕生

1995 年、MIT の数学教授 Tom Leighton と博士課程の学生 Danny Lewin は「どうすれば Web コンテンツを世界に高速配信できるか」を研究した。答えは数学的で、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 位、開発者向け)、Akamai (エンタープライズ)、Fastly (性能)、Amazon CloudFrontGoogle Cloud CDNAzure CDNBunny.netKeyCDN など。

1.3 なぜ CDN が必要か (Latency の数学)

光は 1 秒で 30 万 km、光ファイバーではその 2/3。ソウルからニューヨークまで片道 11,000km、最低 55ms 片道で RTT 110ms。実際はルーティングとキューイングで 180–250ms になる。

TLS + HTTP が 3–4 RTT かかると 1 秒近くになり UX 破綻。CDN は物理距離を縮める — ソウルのユーザがソウルの edge PoP に当たれば RTT 5–10ms。物理法則に勝つのではなく回避するのだ。


2. CDN の三本柱

2.1 ルーティング三位一体

ユーザを最寄りの edge に送る 3 つの仕組み:

  1. Anycast BGP: 同じ IP を複数地域が広告し、BGP が「近い」場所にルーティング。
  2. DNS ベースルーティング (GSLB): ユーザ IP の地域に応じて異なる edge IP を返す。
  3. HTTP リダイレクト: レガシー。

主要 CDN は通常 Anycast と GSLB を併用する。

2.2 Anycast の長所と限界

長所: DNS 変更不要、BGP 速度でのフェイルオーバー、運用シンプル。限界: BGP はネットワーク距離のみ見てサーバ負荷を知らない、route flap で TCP 切断、地理と経路が一致しない場合もある。

2.3 GSLB

DNS ベース。Authoritative サーバが要求者 IP (EDNS Client Subnet があればより正確) の地域に合う edge IP を返す。

(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)

長所: 負荷、遅延、地域規制を考慮した緻密な判定、TCP が 1 edge に固定。限界: DNS TTL がルーティング変更速度を制約、パブリック resolver では位置がズレる。

2.4 PoP (Point of Presence)

地域に置かれた CDN 物理サーバ群。Tier-1 ISP 内部または IXP に配置、数十〜数百台のサーバ、LB、edge、キャッシュストレージを持つ。Tier-1 ISP と直接 peering して BGP 経路で優位に立つ。

Cloudflare は 300+ 都市、Akamai は 4,000+ 拠点。差は戦略 — Cloudflare は主要 IXP の大型 PoP、Akamai は ISP 内部に embedded された多数の小型サーバ。


3. Cache Key — CDN の根本的決定

3.1 役割

CDN がキャッシュからオブジェクトを探す識別子。正しい設計が hit rate を決める。

デフォルト:

scheme + host + path + querystring

例: https://example.com/images/hero.jpg?w=800 がそのまま cache key。

3.2 Vary ヘッダー — 複雑さの始まり

Vary レスポンスヘッダーは「このレスポンスはこのリクエストヘッダーにより変わる」と CDN に伝える。

Cache-Control: public, max-age=3600
Vary: Accept-Encoding, Accept-Language

CDN は cache key を URL + Accept-Encoding + Accept-Language に拡張する。

Vary の罠:

  1. Vary: User-Agent: ブラウザごとにキャッシュ、hit rate 崩壊。絶対禁止。
  2. Vary: Cookie: ほぼ全リクエストで Cookie が異なり、キャッシュ無意味。
  3. Vary が多すぎ: 組合せ爆発。

3.3 Query String 正規化

?utm_source=twitter?utm_source=facebook は同一コンテンツでも別 key になる。CDN の正規化機能で utm_* を除去 (Cloudflare Cache Rules、Fastly VCL)。

Cookie があると通常キャッシュしないが、特定 Cookie のみ意味があれば明示的に分岐 — 匿名ユーザには静的、ログイン済みには SSR。A/B テストは ab_variant Cookie で分岐。

3.5 Device Type 分離

Client Hints の Sec-CH-UA-Mobile を使う。User-Agent 全体を Vary するのはアンチパターン、origin でパースして X-Device-Type のような絞り込んだ値に変換する。


4. HTTP キャッシュヘッダー — 正確な意味

4.1 Cache-Control

最重要ヘッダー。ディレクティブ:

  • public / private: 全キャッシュ可 / ブラウザのみ。
  • no-cache: キャッシュ可だが毎回検証。
  • no-store: 一切キャッシュ禁止。
  • max-age=N: N 秒 fresh。
  • s-maxage=N: CDN 向けのみ。
  • immutable: 不変 (フォント、ハッシュ付き JS)。
  • stale-while-revalidate=N: 期限後 N 秒は stale を返しつつ背景更新。
  • stale-if-error=N: origin エラー時 stale 返却。

4.2 典型パターン

ハッシュ付き静的アセット:

Cache-Control: public, max-age=31536000, immutable

HTML:

Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=3600

公開 API:

Cache-Control: public, max-age=10, stale-while-revalidate=60

個人化: Cache-Control: private, no-cache。機密: Cache-Control: no-store

4.3 ETag と条件付きリクエスト

ETag はレスポンスのバージョン識別子。ブラウザや CDN が If-None-Match: "a3f2b1c4" で再検証し、未変更なら 304 Not Modified を本文なしで返す。

Strong ETag ("abc") はバイト同一、weak (W/"abc") は意味的同一。

4.4 Last-Modified / If-Modified-Since

時刻ベース代替。秒単位で不正確、時計問題あり。現代は ETag 優先。

4.5 stale-while-revalidate — 最も過小評価される機能

Cache-Control: max-age=10, stale-while-revalidate=3600

期限後 1 時間の間: (1) キャッシュ済み stale を即返却、(2) 背景で origin 更新、(3) 以降のリクエストは fresh。ユーザ体感は常にキャッシュ速度、origin 負荷は更新 1 回分。Cloudflare、Fastly、CloudFront 全て対応。

4.6 Age と X-Cache

CDN が付与: Age: 123X-Cache: HITX-Cache-Hits: 5CF-Cache-Status: HIT。デバッグの基本ツール。


5. Origin Shield と Tiered Caching

5.1 問題

edge PoP が数百あり、同じ origin を共有する。人気オブジェクトが期限切れになると数百 edge が一斉に origin を叩き origin 爆発 — Thundering herd。

5.2 Origin Shield

edge と origin の間に単一中間キャッシュ層を挟む:

User -> Edge PoPs (数百) -> Origin Shield PoP (1〜少数) -> Origin

edge miss は Shield へ、Shield miss のみ origin へ。origin 負荷は 10–100 倍減。

5.3 実装

  • Cloudflare Tiered Cache / Argo Smart Routing。
  • AWS CloudFront Origin Shield (region 指定)。
  • Akamai Tiered Distribution (アーキ標準)。
  • Fastly Shielding (クエリで PoP 指定)。

5.4 Cache Coalescing

同一オブジェクトへの同時 miss を edge が 1 回の origin fetch にまとめ、他を待たせる。Nginx proxy_cache_lock、Cloudflare 自動、Fastly デフォルト。バイラル時でも origin は 1 リクエスト。

5.5 階層の進化

Browser cache
 -> Service Worker cache
 -> CDN Edge cache
 -> CDN Regional cache
 -> Origin Shield
 -> Origin

各層 95% 以上の hit ratio で origin 到達は 0.001%。これが「99.9% offload」マーケ数値の実体。


6. Purge — キャッシュ無効化の技術

6.1 なぜ難しいか

数百 PoP のキャッシュを同時に消すにはグローバルメッセージバスが必要。逐次では数秒〜数分、その間古いコンテンツが一部地域に残る。

6.2 戦略

  • URL ベース: 最も一般的。
  • Tag ベース (surrogate key): レスポンスに Surrogate-Key: product-123 を付け、タグで数百ページ一括無効化。Fastly が先駆。
  • Prefix ベース: /products/*
  • 全体 purge: 緊急用。

6.3 速度

Cloudflare: 世界 ~30s、タグで 150ms。Fastly: 150ms。CloudFront: 10–15 分で遅い — アーキ選定の理由になる。

6.4 Versioned URL

<link rel="stylesheet" href="/static/app.v3f2b1a.css">

新デプロイ: 新ハッシュのファイルをビルド、HTML のみ更新 (短 TTL)、旧キャッシュは自然消滅。ほとんどの SPA、Next.js、SvelteKit がこの方式。URL が変われば purge 不要。

6.5 Soft vs Hard Purge

Soft Purge はエントリを stale マーク、SWR で即返却 + 背景更新。UX が滑らか。Fastly が導入、今はほぼ全 CDN が対応。


7. Edge Compute — コードが edge へ

7.1 なぜ

静的キャッシュだけでは扱えないもの — A/B 分岐、認証、geo リダイレクト、個人化、軽量 API 変換。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!');
    }
    return fetch(request);
  }
};

Cold start 5ms 未満 (コンテナの 100ms+ と対比)。128MB/isolate、CPU 10–50ms。1 プロセス内で数万 worker が稼働。

7.3 Workers のエコシステム

  • KV: グローバル KV、結果整合。
  • Durable Objects: 単一インスタンス stateful。
  • D1: SQLite ベースの edge DB。
  • R2: S3 互換、egress 無料。
  • QueuesAnalytics EngineWorkers AI (LLM 推論)。

edge 版 backend-as-a-service。

7.4 Fastly Compute@Edge — WebAssembly モデル

2019 年発表。Wasmtime で WASM 実行。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 50ms 未満。各リクエストが独立 WASM instance で強い隔離。

7.5 AWS Lambda@Edge vs CloudFront Functions

Lambda@Edge: 通常 Lambda、Node.js/Python、cold start 100ms+、4 つの実行点。CloudFront Functions: 2021 年、V8 ベース、1ms 未満、viewer のみ。AWS の Workers 対抗。

7.6 Vercel Edge Functions

Vercel が Cloudflare Workers の上に抽象化。Next.js の export const runtime = 'edge' で edge 実行。2026 年時点で Next.js、Astro、Remix、SvelteKit 全てが edge runtime 対応。

7.7 限界

CPU/メモリ制限、ファイルシステム無し、長寿命接続に制約、デバッグ困難。重処理は依然 origin。


8. 画像・動画最適化

8.1 なぜ画像か

Web ページ送信バイトの 50%+ が画像。最適化 = ロード速度 + 帯域コスト = UX + お金。

8.2 フォーマット

  • JPEG: 互換性王。
  • PNG: 無損失、透過。
  • WebP (2010): JPEG 比 25–35% 小。
  • AVIF (2019): WebP 比さらに 30% 小。
  • JPEG XL: Chrome 実験フラグ。

8.3 Content Negotiation

ブラウザが Accept: image/avif,image/webp,... を送信、CDN が最適フォーマットを 1 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 が ?width=800&format=auto で各バリエーションを生成、各 URL が別 cache key。

8.5 Video — HLS と DASH

HTTP ベース適応ストリーミング。HLS は .m3u8 + .ts、DASH は .mpd、CMAF が共通化。動画を複数解像度 × 複数ビットレートで、2–10s セグメントに分割。CDN から見れば多数の小さな静的ファイルで非常にキャッシュ向き。

8.6 知覚品質メトリクス

PSNR (古典)、SSIM、VMAF (Netflix 2016) — ML で人間評価を予測、業界標準。Netflix は 1 作品を数百組合せでエンコードし VMAF 上位のみ採用、帯域 20% 削減。


9. TLS 終端とセキュリティ

9.1 TLS at Edge

user ↔ edge で TLS 終端、edge ↔ origin は別 TLS (または私設網)。証明書管理の中央化、最新 TLS/QUIC を edge で即展開、handshake RTT 削減。

9.2 Universal SSL (Cloudflare 2014)

全顧客に無料 SSL。SNI で 1 IP に数千ドメイン。Let's Encrypt 前夜の革命。現在は HTTP/3、ECH まで自動適用。

9.3 Origin の保護

edge があっても origin が露出していれば迂回される。防御: Authenticated Origin Pulls (相互 TLS)、CDN IP 範囲のみ許可、origin DNS を公開しない、Cloudflare Tunnel で outbound のみ。

9.4 DDoS 吸収

CDN の帯域容量は Tbps、origin は Gbps。edge が攻撃を吸収。Cloudflare は 228 Tbps (2025)。記録最大攻撃: 398 Tbps HTTP/2 Rapid Reset (2023) を Cloudflare、Google、AWS が同時緩和。

9.5 Bot 管理

トラフィックの 30–50% が bot。正規 (Googlebot) と悪性 (スクレイパー、credential stuffing)。CDN のツール: TLS/HTTP2 fingerprint (JA3)、JS challenge、Cloudflare Turnstile、行動分析、ML スコア。

9.6 WAF

SQL injection、XSS、RCE を edge でブロック。OWASP CRS 基準、カスタムルール、ML で異常検知。Cloudflare WAF、AWS WAF、Akamai AppSec が F5、Imperva のオンプレ代替に。


10. 帯域経済

10.1 Egress の真実

AWS S3、GCS、Azure Blob は egress 課金。2024 年 AWS: 0.09/GB(100TB以下)、月100TB0.09/GB (100TB 以下)、月 100TB で 9,000。

10.2 CDN の経済

CDN は AWS egress の 1/3〜1/5: Cloudflare ~0.02/GBFastly0.02/GB、Fastly 0.12/GB、CloudFront 0.085/GBBunny.net0.085/GB、Bunny.net 0.01/GB。高 hit ratio と組み合わせて origin egress は 99%+ 削減。

10.3 R2、B2 — Zero Egress

Cloudflare R2 と Backblaze B2 は egress 無料。R2: S3 互換、egress 0、ストレージ0、ストレージ 0.015/GB。Bandwidth Alliance (Cloudflare、Backblaze、DigitalOcean、Wasabi) 間は相互 egress 無料。

10.4 Peer-Assisted

Netflix Open Connect は ISP 内部にサーバ配置、ISP ユーザは ISP 内で動画取得、ISP の対外帯域も節約で歓迎される。P2P 方式 (WebTorrent、Peer5) はライセンス/プライバシーで限定的。

10.5 Hit Ratio の経済

95% から 99% への改善で origin 費 5 倍削減。cache key、TTL、purge 設計の ROI は巨大。


11. 実装

11.1 Cache-Control テンプレート

# ハッシュ付き静的
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 Cache Rules

# /static/* 長期キャッシュ
Match: (http.request.uri.path matches "^/static/")
Action: Cache Everything, Edge TTL 1y, Browser TTL 1y

# /api/* バイパス
Match: (http.request.uri.path matches "^/api/")
Action: Bypass

# ログイン 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 最適化

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 監視指標

cache hit ratio は 90% 超を目標。origin RPS、地域別 p99 latency、egress バイト、5xx rate を観測。

11.6 アンチパターン

  • Cache-Control 未設定でブラウザ heuristic 任せ。
  • Vary: User-Agent
  • Cookie 依存ページをキャッシュ — データ漏洩。
  • PII をクエリストリングに。
  • 頻繁な全体 purge。
  • CDN が origin の Cache-Control を黙って override。

12. 最新トレンド

12.1 HTTP/3 at Edge

Cloudflare、Fastly、CloudFront 全てデフォルト。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 で。全 PoP に GPU は無理 — 主要 PoP に GPU、他は最寄り GPU PoP にルーティング。

12.4 Zero Trust

Cloudflare One、Akamai Zero Trust、Zscaler。CDN edge が企業網ゲートウェイとなり VPN を代替、identity ベースアクセス制御。

12.5 WebAssembly Components

Component Model による安全な多言語合成。Fastly Compute@Edge が先導。


13. 運用者 Tips

13.1 デバッグ

curl -I https://example.com/page
curl -I https://example.com/page -H "X-Cloudflare-Debug: 1"

CF-Cache-StatusX-CacheAge を確認。MISS 連発なら cache key 再検討。

13.2 Warming

デプロイ後や新地域追加時、主要 URL を事前リクエスト:

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 は認識せず、ユーザ別 variant は Cookie で固定。

13.4 インシデント対応

「急に origin にトラフィックが集中」: hit ratio 低下、最近の purge、Cache-Control 変更、5xx 急増 (5xx 非キャッシュで origin 連打)、Vary に新値追加、を順にチェック。対応: 一時的に Origin Shield 有効化、Edge TTL 強制、WAF ルール。

13.5 Cache Poisoning

攻撃者がヘッダーを改竄 → origin が汚染レスポンス生成 → CDN キャッシュ → 全ユーザ感染。例: X-Forwarded-Host: attacker.com がリンクに使われる。防御: 疑わしいヘッダーの除去、cache key は信頼できる入力のみ、canonicalization。James Kettle の 2018 DEF CON 発表が古典。


結び — Bytes をユーザの隣へ

CDN の本質は単純だ — バイトをユーザの隣に置け。この単純な原則が現代 Web の速度と経済性を支える。

運用者の 3 反射:

  1. cache hit ratio を測る。90% 以上が基本。
  2. Cache-Control を意図的に書く。SWR は必ず追加。
  3. Origin Shield / tiered cache を使う。無料/低コストで origin 負荷 10 倍減。

直近 3 記事でリクエスト経路を追跡した:

  • DNS: 名前解決。
  • TLS 1.3 + QUIC: 安全チャネル。
  • CDN (本記事): バイトの配達。

次回は Git 内部 — オブジェクトモデル、refs、packfile、rebase の実装