Vercel、
中身どうなってるの?
完結編。

最後は一番深く。
Edge Function、なぜそんなに速いのか?
VOL.3 / 仕組みの最深部へ

Vol.2 で 一つだけ
後回しにしたものがあります

Vol.2 では Edge Function の Cold Start が ~5ms と話しました。
Serverless Function は 数百ms〜数秒。なぜそんなに違うのか?
その答えが V8 Isolates という仕組み。 — Chrome がタブを分離するのに使ってる技術が、Vercel の Edge Function を支えてます。
今日はこの「便利の正体」の最後のピースを覗いてみます。OS、コンテナ、VM、Isolate…という階層の話になります。
— PROLOGUE

「コードを動かす」の
分離レベルは色々ある

同じ Linux サーバー上で、どこまで他人と分けるか
クラウドで他人のコードと一緒に動かすには「ちゃんと分離」しないと危ない。でも分離は 重い ほど安全で、軽い ほど速い。トレードオフです。
1. 物理サーバー / OS
そのまま動かす。最速だけど分離ゼロ。クラウド時代では論外。
起動: 0ms
2. 仮想マシン (VM)
OS ごと分ける。完全分離だけどメモリ・起動コスト大。例: 普通の EC2
起動: ~1-2秒
3. MicroVM (Firecracker)
VM を超軽量化。Linux kernel は薄く、デバイスは最低限。AWS Lambda の中身。
起動: ~100-500ms
4. V8 Isolate
OS も VM もなし。1 個の V8 プロセスの中で、メモリ空間だけ分ける。Vercel Edge Function。
起動: ~5ms以下
Vercel は用途によって 3 と 4 を使い分けて います。それを今日は深掘りします。
— CHAPTER 01 / 03

Firecracker

AWS Lambda の中身、Vercel Serverless の中身
素朴な疑問
「Serverless」って結局、裏では何が動いてるの?

Vercel の Serverless Function は AWS Lambda の上で動いているそうです。そして AWS Lambda の中身は Firecracker という超軽量 VM 技術。

普通の VM は OS まるごと立ち上げて 1〜2 秒かかるところ、Firecracker は 必要最低限のものだけ載せた Linux カーネル を起動するので 100〜500ms に短縮できる、という技術。

AWS が OSS として公開しているので、誰でも仕組みが見られます。中身は Rust 製。

普通のVM (EC2など):
┌─────────────────┐
│ OS + 全デバイス │   起動 ~数秒
│ + ネットワーク等│   数百MB
└─────────────────┘

Firecracker microVM:
┌─────────────────┐
│ 薄いLinux起動 ~125ms最小デバイス~5MB
└─────────────────┘

トレードオフ:
  + 完全な OS 互換性
  + 強い分離 (KVM)
  − それでも数百ms かかる
TERM
Firecracker
AWS 製の軽量 VM。Linux kernel を最小構成で起動。AWS Lambda・Fargate・Vercel Serverless など、サーバーレス基盤の裏で広く使われている。OSS。

"Functions" の箱の中を、もっと拡大してみる

Vol.2 で見たリクエストの内部フロー図、一番右の Vercel Functions の箱には、実は 2 種類の Function が並んで入っていました。
VERCEL EDGE NETWORK (Vol.2) FW Routing Cache Functions ← ココ ZOOM IN VERCEL FUNCTIONS の中身 — EDGE FUNCTION V8 Isolate V8 Process (常駐) Iso A Iso B あなたのJS Iso D Iso E Iso F Cold Start ~5ms — SERVERLESS FUNCTION Firecracker microVM AWS Lambda の中身 あなたの Node.js コード npm 依存パッケージ 薄い Linux Kernel Cold Start ~100-500ms
今日は、この 2 つの箱の中身 を解剖していきます。なぜ Cold Start が 100 倍違う のか、見えてくるはず。
— CHAPTER 02 / 03

V8 Isolates

Chrome のタブ分離技術を、サーバー側で使う発想
素朴な疑問
そもそも V8 って Chrome の中身じゃないの?それをサーバーで使うってどういうこと?

V8 は JavaScript エンジン。Chrome や Node.js の心臓部です。1 つの V8 プロセスの中で、複数のメモリ空間を分けて持つ仕組みが Isolate

Chrome では「タブ A の JS が、タブ B の変数を覗けない」ようにするのに使われています。これをサーバーに持ち込んで「ユーザー A の関数が、ユーザー B のメモリを見られない」を実現したのが Edge Function。

VM ごと立ち上げる必要がない(V8 プロセスは常駐)ので、Cold Start が一気に ~5ms 以下になる。

V8 Process (常駐):
┌──────────────────────────┐
│ ┌────────┐  ┌────────┐  │
│ │Isolate A│  │Isolate B│ │
│ │あなたの│  │他人の  │  │
│ │ JS     │  │ JS     │  │
│ │heap+gc │  │heap+gc │  │
│ └────────┘  └────────┘  │
│                          │
│  ┌────────┐  ┌────────┐  │
│  │Isolate C│  │Isolate D│ │
│  │別の人  │  │また別  │  │
│  └────────┘  └────────┘  │
└──────────────────────────┘

※ 1プロセスに数千の isolate が同居
※ 起動はメモリ確保だけ → 数ms
TERM
V8 Isolate
V8 JS エンジンが提供する「分離された実行環境」。それぞれが独自の heap・GC を持ち、メモリは完全に分離。元々は Chrome のタブ分離用。
— CHAPTER 02 (続き)

なぜ 100 倍速いのか?

起動するものが、そもそも違う
Lambda と Edge Function、起動時にやることを並べてみると、差は一目瞭然でした。
段階 AWS Lambda (Firecracker) Edge Function (V8 Isolate)
VM の確保 必要 ~50-200ms 不要(V8 は常駐済み)
OS ブート Linux kernel 起動 不要
ランタイム起動 Node.js プロセス起動 不要(V8 常駐)
コード読み込み npm依存含めて全部 軽量な JS のみ
Isolate 作成 ~数ms(メモリ確保のみ)
合計 ~100-500ms+ ~5ms 以下
「ゼロから何かを立ち上げる」のではなく「既にあるプロセスに居候させてもらう」。これが Isolate の発想。
— CHAPTER 03 / 03

Edge の 制約はどこから来てるか

速さの裏には、必ず代償がある
「Edge は速い」と聞くと「全部 Edge でいいじゃん」と思いがちですが、できない事もそれなりに多い。その制約は、すべて Isolate の仕組みから来てます。
CONSTRAINT 01
Node.js API が使えない
なぜ? V8 は JS エンジンだけ。Node.js の fs, net, child_process などは存在しない。fetch などの Web 標準 API のみ。
CONSTRAINT 02
ネイティブモジュール禁止
なぜ? C++ で書かれた npm パッケージは動かない。sharp(画像処理)や bcrypt なども不可。Pure JS のみ。
CONSTRAINT 03
実行時間に厳しい上限
なぜ? 1 プロセスに数千 isolate が同居しているので、1 個が長く CPU を占有すると他に迷惑。デフォルトで秒〜分単位の上限。
CONSTRAINT 04
メモリも厳しい
なぜ? 同じ理由。Edge Function は数百 MB 単位。Serverless Function は GB 単位まで使えるので、重い処理はこちら向き。
「軽くて速い」と「重くて何でもできる」。同じ Serverless でも、求められる場面が違うんだなと整理できました。
— SUMMARY

Vercel は 2 つを使い分けていた

「Edge か Serverless か」は技術選択の最前線
項目 Edge Function (V8 Isolate) Serverless Function (Firecracker)
裏側の技術 V8 Isolate AWS Lambda / Firecracker
Cold Start ~5ms 以下 ~100-500ms
使える API Web 標準 (fetch など) Node.js フル
ネイティブ依存 不可
実行時間上限 短い 長い (最大15分)
地理的配置 世界中の PoP 選択した1〜数リージョン
得意な用途 認証チェック / リダイレクト / A/Bテスト / 軽量API DBアクセス / 画像処理 / 重い計算 / SSR
Vercel は「全部 Edge」じゃなく、適材適所で振り分けてくれる。これが Vol.1 で言った「適材適所」の正体でした。

Vercel の便利さは、
階層になった抽象化でできていた

— VOL.1
全体像
Webhook → Build → 配布 → Atomic Deploy → PoP配信。git push の裏では 5 ステップ。
— VOL.2
仕組みの裏側
Anycast で最寄り拠点へ自動振り分け。ISR で "古いの出しつつ裏で更新"。Cold Start の話。
— VOL.3
最深部
Firecracker (microVM) と V8 Isolate を使い分け。「速さ」と「何でもできる」のトレードオフ。
— TAKEAWAY
Vercel が魔法に見える理由は、古典的なインフラ技術を、これだけ綺麗に隠して組み合わせているから。
— 「便利の正体」は、たぶん他のサービスでも同じ構造で隠れているはず。

もっと知りたい人向け リンク集

今日の話の核は Firecracker と V8 Isolate。どちらも OSS で、設計ドキュメントや論文まで読めます。ガチで知りたい人は AWS の NSDI 論文がおすすめです。
GITHUB / OSS ★Firecracker 本体
firecracker-microvm/firecracker
github.com/firecracker-microvm/firecracker
AWS 製の microVM。Rust 製、Apache 2.0。125ms 起動・5MiB オーバーヘッドの根拠
AWS PAPER ★ガチ向け
Firecracker: Lightweight Virtualization (NSDI'20)
assets.amazon.science/.../firecracker-lightweight-virtualization.pdf
設計思想と Lambda 実装の論文。「なぜ既存 VMM じゃなく自作したか」の答え
AWS BLOG
Firecracker 発表ブログ
aws.amazon.com/blogs/aws/firecracker-lightweight-virtualization
Lambda と Fargate を支える技術として 2018 年に OSS 公開された経緯
V8 / CHROMIUM
V8 JavaScript Engine
v8.dev / chromium.googlesource.com/v8/v8
V8 本体。Isolate API のドキュメントから "なぜ Chrome のタブ分離技術が Edge で使えるか" が読み取れる
VERCEL DOCS
Edge Runtime
vercel.com/docs/functions/runtimes/edge
Vercel が V8 Isolate を採用した Edge ランタイムの仕様、Node.js API 制限
CLOUDFLARE BLOG ★Isolate 解説
How Workers works (V8 Isolates)
blog.cloudflare.com/cloud-computing-without-containers
V8 Isolate ベースのサーバーレスの先駆者 Cloudflare による解説。"なぜ Lambda より速いか" の説明が分かりやすい

便利を 使う側 から、
便利を 理解する側
なれた気がします。

Webhook、Anycast、V8 Isolates、Firecracker…
どれも他のサービスでも顔を出す概念だった。インフラ勉強の起点として、最高のテーマでした。
VOL.3 / 完。3週間ありがとうございました
1 / 11