Cloudflare Workers+Hono:なぜ選ぶのか・どう動くのか・いつ避けるのか
2026-07-29
#Cloudflare#Workers#Hono#サーバーレス#エッジ#TypeScript
「ちょっとしたAPIが欲しい」のためにVPSを借りてnginxを設定するのは、2026年にはもう重い。かといって選択肢は Cloudflare Workers だけではなく、Lambda@Edge も Vercel も Deno Deploy も Fastly もある。この記事は「入門手順」ではなく、Workers+Hono を選ぶかどうかを自分で判断できるようになることを狙って書く。仕組み・料金の理屈・他との比較・向き不向きを、図と一次情報(各社公式ドキュメント)で並べる。
数値・仕様は変動するので、料金や上限は執筆時点(2026年7月)の各社公式を基準にしている。最終判断の前には必ず一次ソースを確認してほしい。
要点(先に結論)
- Workers は V8 isolate1 で動くので、Lambda のような microVM の起動待ち(コールドスタート2)が実質ない
- 安いのは CPUを使った時間だけ課金だから。
fetchや DB 待ちのアイドル時間は課金されない。無料枠は1日10万リクエスト - Hono は Web 標準ベースの軽量フレームワークで、Workers 以外(Deno/Bun/Node/Vercel/Lambda)でも同じコードが動く。Workers で書くならまずこれ
- 向くのは「軽い処理を大量に捌く」用途(API・Webhook・BFF3・フォーム受け)。向かないのは常駐接続・数十秒の重い処理・Nodeネイティブ依存
- 迷ったら記事末尾の判断フローで切り分けられる
Workers はどう動くのか(なぜ速い)
Cloudflare のエッジ4(世界330都市以上、120以上の国)で JavaScript/TypeScript を実行するサーバーレス環境。AWS Lambda と役割は似ているが、動く単位が違う。
Lambda は関数ごとに microVM(言語ランタイム入りの軽量VM)を立てる。だからしばらく呼ばれていない関数は、それを起動し直す「コールドスタート」で数百ミリ秒〜秒の待ちが発生する。Workers は関数ごとに microVM を作らず、既に動いているプロセスの中に isolate を生成する。isolate は Chrome のタブと同じ隔離単位で、1つのランタイムが数百〜数千の isolate をメモリ分離したまま切り替えながら動かす。
Cloudflare の公表では、isolate はコンテナ上の Node プロセスより約100倍速く起動し、Worker のロードは約5ミリ秒で済む(5msは2018年の初出値で、以降さらに短縮されている)。さらに TLS ハンドシェイク5の段階で Worker をプリロードするため、実リクエストが届くころには準備が終わっている。クライアント〜Cloudflare 間のレイテンシの方がロード時間より長いので、ユーザーから見たコールドスタートが実質ゼロになる、という理屈だ。
「エッジで世界配信」って何をしているのか
バックエンドのコードなのに「世界中のエッジで動く」というのは、言葉だけだとフワッとする。ここを具体的に分解しておく。
従来は、コードを1箇所のサーバーに置く。 例えば東京のVPSにAPIを立てると、コードが動くのは東京だけ。ブラジルのユーザーは、リクエストのたびに地球の裏側まで往復することになる。物理的な距離の分だけ遅い。
Workers は、あなたのコードを全拠点に複製する。 wrangler deploy を1回打つと、数百KB〜数MBの小さなJS/TSの束(スクリプトの上限は無料3MB・有料10MB/gzip後)が Cloudflare の330以上の拠点すべてにコピーされる。「1台のサーバーがどこかにある」のではなく、同じコードが世界中に配られている状態になる。そしてリクエストが来ると、Anycast6 という仕組みが自動的に最寄りの拠点へ振り分け、そこであなたのコードが動く。ユーザーの近くで実行されるから速い。
リクエスト1本の目線で追うとこうなる。「到達するまで(ルーティング)」と「到達した後(拠点の中での実行)」に分けて見ると分かりやすい。
なぜこんなことが可能なのか
「コードを世界中に配って、来たとき動かす」が成り立つのには理由がある。
- コードが軽くて持ち運べる。 isolate は OS やコンテナごと運ぶ必要がなく、JSの束だけ配ればいい。VMイメージを330拠点に常時置くのは非現実的だが、数MBのコードなら世界中に配れる
- 起動が速いので、専用サーバーを常時確保しなくていい。 isolate は約5msで起動するから、各拠点は「あなた専用のマシン」を24時間空けておく必要がない。リクエストが来た拠点で、その場で動かせる
- 土管が最初からある。 Cloudflare はもともと画像やHTMLを世界配信するCDNの巨大network(330拠点)を持っている。Workers はその同じ配信網に相乗りしている。だからCloudflare側の追加コストが小さく、結果としてあなたの料金も安い
正直な但し書き:簡単に世界配信できるのは「計算」だけ
ここは誤魔化さずに書く。世界中に複製できるのはコード(=ステートレスな計算)の話で、データ(DB)はそう簡単には世界中へ置けない。 東京の近くで動く Worker が米国のDBを叩けば、そのDBまでの往復は結局残る。
だから Cloudflare は「データ側もエッジに寄せる」ための道具を別に用意している——キーバリューストアの KV、エッジで動くSQLiteの D1、状態を1箇所に固定して整合を取る Durable Objects などだ。ステートレスな処理ほどエッジの恩恵が素直に効き、状態を持つほど設計が要る。「Workersにすれば何でも自動で速くなる」ではなく、「計算はエッジに出せる。データは別途エッジ寄せの設計をする」が正確な理解になる。
なぜ安いのか
「エッジで世界配信」と聞くと高そうだが、Workers の料金は安い。理由は課金の測り方にある。
CPU時間で課金され、待ち時間は課金されない。 Workers の課金対象は「あなたのコードが実際に CPU を使った時間」で、fetch()・KV7 読み取り・DB クエリなどのネットワーク待ちは CPU時間に含まれない。実時間(wall-clock)ではなく CPU時間なので、「外部APIの応答を3秒待つAPI」でも、待っている間は課金されない。実時間そのものには課金も上限もない(HTTPトリガーの場合)。
料金はざっくり以下(2026年7月時点)。
| 無料プラン | 有料プラン($5/月〜) | |
|---|---|---|
| リクエスト | 10万/日 | 1,000万/月込み、超過 +$0.30/100万 |
| CPU時間 | 10ms/リクエスト | 3,000万CPU-ms/月込み、超過 +$0.02/100万ms |
| CPU時間の上限 | 10ms/リクエスト | デフォルト30秒(最大5分まで引き上げ可) |
| メモリ | 128MB | 128MB |
感覚としては、フォーム受付・Webhook・小さなAPIなら無料枠から出ることはほぼ無い(10万/日 ≒ 1.16リクエスト/秒。常時トラフィックのある本番APIは普通に超えるので、そこは有料前提で見積もる)。CPU時間10msは「JSONを捌いて返す」には十分で、逆に画像処理のような重い計算をやると引っかかる。
Hono を薦める理由
Workers は「関数を1つ export する」だけでも動くが、ルーティング・バリデーション・ミドルウェアが欲しくなる。そこで Hono を使う。
- Web標準APIだけで書かれ、ゼロ依存。 バンドルは軽い(公式サイト表記で
hono/tinyが14kB未満。GitHub README では12kB未満と表記があり、出典で数値が少し割れる)。Express の約572KB と対比されている - マルチランタイム。 公式が挙げるだけで Cloudflare Workers / Fastly Compute / Deno / Bun / Vercel / Netlify / AWS Lambda / Lambda@Edge / Node.js に対応。同じコードが載せ替えできるので、Workers に縛られずに済む
- ルーターが速い。 既定では複数ルーターから最速を選ぶ仕組みで、中核の
RegExpRouterはルートを1つの大きな正規表現にまとめて一度のマッチングで解決する(線形ループを使わない)。公式は「JavaScript界で最速」と主張している(定量ベンチは公式一次ページでは未確認なので、ここは定性表現に留める) - TypeScriptの型が効く。
new Hono<{ Bindings: {...}, Variables: {...} }>()と書くと、c.env(環境変数・バインディング)とc.set/c.get(コンテキスト変数)に型が付く
ちなみに Express をそのまま Workers に載せるのは素直にはいかない。Express は Node 固有APIが前提で、Workers は net.Server(TCPで待ち受けるサーバー)を張れないため、互換フラグやブリッジが要る。最初から Web 標準で書かれた Hono を使う方が早い。
他の選択肢と比較
エッジ/サーバーレスでコードを動かす手段は Workers だけではない。位置づけを2軸(制約の強さ × 運用の手軽さ)で並べるとこうなる。
| 選択肢 | 実行モデル | 実行時間の目安 | 向く用途 |
|---|---|---|---|
| Cloudflare Workers | V8 isolate | CPU 10ms(無料)〜5分(有料) | API・Webhook・BFF・フォーム受け |
| CloudFront Functions | 軽量JS(ES5.1+async等) | サブミリ秒 | ヘッダ操作・リダイレクト・キャッシュキー正規化 |
| Lambda@Edge | コンテナ(Node/Python) | 最大30秒 | SDK/ネットワークを使う本格的な書き換え・認証 |
| Vercel Functions | Node.js / Edge(isolate) | Node は300秒〜(延長可) | Next.js 前提のアプリ・汎用API |
| Deno Deploy | V8 isolate | インスタンス寿命ベース | TypeScript/Web標準ネイティブなAPI・SSR |
| Fastly Compute | WebAssembly8 | 最大2分・CPU 50ms/req | Rust等で高性能なエッジ処理 |
| 素のNode.js+VPS | 常駐プロセス | 無制限 | WebSocket・長時間処理・任意ライブラリ |
比較にあたって、古い情報が出回りやすい点を補足しておく(いずれも執筆時点で確認済み)。
- Lambda@Edge のタイムアウトは全トリガー最大30秒。 昔あった「viewer 1秒 / origin 5秒」は現行では正しくない
- Vercel の「Edge Functions」は独立製品としては非推奨になり、
runtime: 'edge'というランタイムオプションに統合された。既定は Node.js ランタイム。料金も Active CPU ベースに変わっている - Deno Deploy は2026年2月に新GAへ全面刷新。旧「Deploy Classic」(10万req/日などの旧数値)は2026年7月20日に停止済み(本記事公開時点でEOL)
- Fastly Compute の公式SDKは Rust / JavaScript / Go(C++は実験的扱い)。課金も新規顧客は「リクエスト数+vCPU ミリ秒」で、旧GB秒課金は廃止された
ざっくりの棲み分け:超軽量なヘッダ操作だけなら CloudFront Functions が最安。重い処理や既存のNode資産を使いたいなら Lambda@Edge か素のサーバー。Next.js に寄せるなら Vercel。TypeScript/Web標準志向で汎用APIを軽く速く公開したいなら Workers+Hono、という並びになる。
出典: CloudFront edge functions / Vercel runtimes / Deno Deploy is GA / Fastly Compute
向くケース / 向かないケース
向いている
- お問い合わせフォームの受け口(メール送信APIへの中継)
- 外部サービスの Webhook 受信
- フロントエンドのBFF(APIの束ね・キー隠蔽)
- リダイレクタ・短縮URL・OGP画像の動的生成
- 「軽い処理を、世界中どこからでも速く」返したいもの全般
向いていない
- 数十秒かかるバッチ処理(CPU時間制限に当たる。Queues や cron と組み合わせて分割する設計になる)
- WebSocket の常駐接続(Durable Objects9 という別の仕組みの領分)
- Node のネイティブ拡張(C++アドオン等)に強く依存するライブラリ(isolate 構造上そもそも動かないものがある)
3つの質問で切り分けると速い。
最短で動かす(5分)
理屈が分かったら手を動かすのは速い。npm create hono@latest → wrangler deploy の2ステップで、APIが *.workers.dev のURLで世界に公開される。
npm create hono@latest my-api
# テンプレートで cloudflare-workers を選ぶ
cd my-api
npm install
npm run dev # http://localhost:8787 でローカル起動
生成される src/index.ts はこれだけ。少し実用寄りに、JSONを返すAPIとパスパラメータ、環境変数の型付けを足す:
import { Hono } from "hono";
// c.env に型を効かせる(wrangler secret で入れた値もここに来る)
const app = new Hono<{ Bindings: { API_KEY: string } }>();
// GET /api/time → 現在時刻を返す
app.get("/api/time", (c) => c.json({ now: new Date().toISOString() }));
// GET /api/greet/:name → パラメータを受ける
app.get("/api/greet/:name", (c) => {
const name = c.req.param("name");
return c.json({ message: `こんにちは、${name}さん` });
});
// POST /api/echo → ボディを受ける
app.post("/api/echo", async (c) => {
const body = await c.req.json();
return c.json({ received: body });
});
export default app;
デプロイは1コマンド:
npx wrangler deploy
# → https://my-api.<あなたのサブドメイン>.workers.dev が発行される
これで終わり。HTTPS・独自ドメイン割当・世界配信が全部ついてくる。nginxもcertbotもsystemdも登場しない。
最初に踏むハマりどころ
- Node APIが素では無い。
BufferやcryptoなどNode組み込みに依存するパッケージは、wrangler.tomlにcompatibility_flags = ["nodejs_compat"]を足す(互換日付を2024-09-23以降に)と動くものが多い。ただし対応は Node API のサブセットで、node:http2node:vm等は非機能スタブ、ネイティブ拡張系は動かない - 秘密情報は
.envではなくwrangler secret put。.envをデプロイに含める仕組みは無く、npx wrangler secret put API_KEYで登録してc.env.API_KEYで読む c.envの型付けは最初に。 上のコードのようにnew Hono<{ Bindings: {...} }>()を書いておくと、後から環境変数を増やしても型で守られる
まとめ
- Workers が速いのは isolate だから。安いのは CPU時間だけ課金だから。この2つが理解できれば「なぜ選ぶか」は説明できる
- Hono は Web 標準ベースで軽く、載せ替えも効く。Workers で書くならまずこれ
- 選択肢は他にもある。超軽量は CloudFront Functions、重い処理や既存Node資産は Lambda@Edge か素のサーバー、Next.js は Vercel。Workers+Hono は「軽いAPIを速く・安く・世界に」出す枠で強い
- 制約(CPU時間・常駐不可・Node互換)は「軽い処理を捌く場所」と割り切れば気にならない
次回はこの Workers に D1(エッジで動くSQLite) を繋いで、DB付きAPIをサーバーレスで組む。うちはこの構成でいくつかサービスを作っているので、同種の技術選定や開発の相談はこちらから。
Footnotes
-
V8 isolate(アイソレート) … V8 は Chrome や Node.js の中で JavaScript を動かすエンジン。その中で作れる「隔離された実行区画」が isolate で、Chromeの各タブと同じ単位。1つのプロセスの中に多数の isolate を並べ、メモリを互いに分離したまま動かせる。コンテナやVMより桁違いに軽く、起動が速い。 ↩
-
コールドスタート … しばらく呼ばれていない関数を動かすとき、コンテナやVMを起動し直すために生じる最初の待ち時間。Lambda型では数百ミリ秒〜秒かかることがある。Workers は isolate を使うため、これが実質ゼロになる。 ↩
-
BFF(Backend For Frontend) … フロント専用の薄いサーバー層。複数APIの呼び出しをまとめたり、APIキーをブラウザに晒さず裏で保持したりする「フロントとバックの間の中継役」。 ↩
-
エッジ … 利用者に物理的に近い、世界中に分散した拠点(データセンター)のこと。中央の1箇所ではなく「端(edge)」で処理することで、通信の往復距離を縮めて速くする考え方。 ↩
-
TLS ハンドシェイク … HTTPS通信の最初に、暗号化の鍵を決めるためにクライアントとサーバーが数往復する手続き。Cloudflare はこの手続きの最中に Worker を先読みしておくため、通信が確立する頃には実行準備が終わっている。 ↩
-
Anycast … 同じIPアドレスを世界中の複数拠点に割り当てておき、利用者からの通信を自動的に「最も近い(速い)拠点」へ届けるネットワーク技術。ユーザーは意識せず最寄りの Cloudflare 拠点に繋がる。 ↩
-
KV … Cloudflare の Workers KV。キーと値をペアで保存する簡易ストレージで、世界の各拠点に読み取り用のコピーが配られる。設定値やキャッシュのような「読みが多く、多少の反映遅れを許せるデータ」に向く。 ↩
-
WebAssembly(Wasm) … ブラウザやサーバーで動く、言語非依存の低レベル実行形式。Rust・Go・C++ などをコンパイルして高速に動かせる。Fastly Compute はこの Wasm をエッジ実行の土台にしている。 ↩
-
Durable Objects … 状態を世界に散らさず「1箇所」に固定して整合を保つための仕組み。WebSocketの常駐接続や、チャットルーム・カウンタのように「1つの正しい状態」を持ちたい用途で使う。通常のWorkersとは別立て。 ↩