◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Claude Code
⟐ Claude Code/2026-05-28上級

Cloudflare Workers の 62 MiB 上限を踏んだ朝に、5,000 記事規模で組み直した Content Split アーキテクチャ

個人で 4 ブログを Cloudflare Workers + Next.js で運用していたある朝、articles.json が肥大化して Worker bundle が 62 MiB 上限を踏み、デプロイが止まりました。メタデータと HTML 本文を分離する Content Split Architecture に組み替えた具体的な実装と、切り替え 1 ヶ月で観測したビルド時間・キャッシュ効果・運用上の落とし穴を共有します。

Cloudflare Workers16Next.js8Content Split個人開発130本番運用36OpenNext

✦ プレミアム記事

ある朝、4 つ並べて運用している AI 技術ブログのうち、Claude Lab だけが急にデプロイ失敗で止まりました。ログを見ると Script startup exceeded CPU time limit ではなく、見慣れない Your Worker exceeded the size limit of 62 MiB という一文が並んでいます。前日の push までは普通にデプロイされていたので、原因は前日に追加した 4 本の MDX のどこかにあるはずでした。

私は 2014年から個人開発でアプリを公開し続けて12年、累計5,000万ダウンロードを超える壁紙アプリと癒し系アプリを運用しています。アーティストとしての国際芸術賞 17冠の活動と並行して、2026 年からは Dolice Labs として 4 サイトの AI 技術ブログを Cloudflare Workers + Next.js(OpenNext)で並行運用しており、合計記事数はちょうどこの日 4,500 本を超えたところでした。「気がついたら壁にぶつかっていた」のは、まさに記事数が静かに積み上がっていたためです。

宮大工をしていた両祖父からは「丁寧に作るというのは、後から触る人のために線を引いておくことだ」と教わった気がしています。62 MiB 上限の壁は、まさに自分が後から触る自分への線引きが足りていなかった証拠でした。今回は、その壁を直接踏みながら、メタデータと本文を分離する Content Split Architecture に組み替えた具体的な手順を残しておきます。

62 MiB 上限を踏んだ朝に最初にやった切り分け

Cloudflare Workers の 62 MiB はバンドル後(Brotli 圧縮後)のサイズ制限です。OpenNext を通した Next.js は Server Components や middleware を含めて一つの Worker bundle に詰め込まれるため、コードだけでなく bundled 扱いになっている静的データも全部この上限に乗ります。

最初にやったのは、デプロイ前のローカルビルドで実際のサイズを見ることでした。

cd /tmp/repos/claudelab.net
npm run build
ls -lh .open-next/worker.js
# -rw-r--r--  1 user  staff   18M  May  3 09:14 worker.js

18 MB は Brotli 前のサイズですが、ここに 4,500 本の MDX を JSON 化したものがほぼ全部入っていることを du -sh で確認しました。src/generated/articles.json 単体で 18 MB を超えていました。

ls -lh src/generated/articles.json
# -rw-r--r--  1 user  staff   18M  May  3 09:14 articles.json

ここでようやく、これまで articles.json 一つにメタデータも HTML 本文も全部詰め込んでいたことが致命傷だと気づきました。1 本あたり 4 KB 程度でも、4,500 本で 18 MB です。さらに 1 日 4 本ペースで増えていきますから、放っておけば 3 ヶ月で 25 MB を超え、半年後には 30 MB を超えます。Brotli 圧縮率が良くても、JSON 内の HTML は重複部分が少なく、圧縮後サイズの伸びはほぼ線形でした。

articles.json を太らせていた設計の限界

そもそも初期設計では、ビルド時に generate-content.mjs が MDX を全部読み込み、メタデータとレンダリング済み HTML を articles.json 一つに集約していました。理由は単純で、Server Components から import articles from "@/generated/articles.json" だけで全記事にアクセスできるからです。

// 旧 generate-content.mjs(要約)
const articles = [];
for (const file of allMdxFiles) {
  const { data, content } = matter(fs.readFileSync(file));
  const html = await mdxToHtml(content);
  articles.push({ ...data, slug, html });
}
fs.writeFileSync("src/generated/articles.json", JSON.stringify(articles));

この設計は 100 本のときは便利でした。500 本でも気にならないサイズでした。1,000 本を超えた頃から「ローカルビルドが遅いな」と感じるようになり、2,000 本で「fs.readFileSync の起動コストが見えるな」と思い、3,500 本で「IDE のオートインポートが重いな」と感じ、4,500 本で 62 MiB を踏みました。後から触る自分への線引きが、気づかないうちに細っていたのです。

ここで線を引き直すべきは、メタデータと本文を物理的に別ファイルに分けるという一点でした。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦Worker bundle が 62 MiB 上限を踏んだ瞬間の症状切り分け手順と、articles.json が 18 MB を超えていた原因の特定方法
✦generate-content.mjs に二段階出力(メタデータ JSON + 本文 HTML を public/content/ に個別書き出し)を仕込む実装と、ASSETS バインディング経由でフェッチする getArticleContent() のコード
✦Cloudflare CI の prebuild フックで自動実行させる package.json の構成と、5,000 記事規模で観測した Worker bundle サイズ 18 MB → 2.4 MB の比較値
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

⟐ Claude Code2026-08-19
一度キャッシュに載った500ページは、直しても消えません
修正をデプロイしたのに壊れたページが出続けたことがあります。原因はコードではなくエッジキャッシュでした。ステータスコードだけを見る保存判定が、200で返る壊れたHTMLを通していたのです。本文の完全性で保存可否を決めるガードの実装と、運用で調整した誤検知の線引きを、実際に踏んだ経緯とともに書きました。
⟐ Claude Code2026-10-12
SPM に移したら、起動した瞬間にアプリが落ちるようになりました — dyld の一行を Claude Code と読み解いた記録
CocoaPods から Swift Package Manager へ移した直後、ビルドは通るのに起動した瞬間に落ちました。dyld の一行から原因を切り分け、直し方と確認コマンドまでをまとめます。
⟐ Claude Code2026-09-20
Pro を払っているのに Console に請求が立っていたとき、私が最初に見た一行
サブスクリプションと API の従量は別会計で、Claude Code はそのどちらでも動きます。どちらが選ばれているかを決めるのは優先順位で、ログインはその最下段です。status の読み方と、無人実行だけが別の答えを返す理由を書き残します。