Vercel のデプロイメントストレージを 13.96 GB から 20.27 MB に減らす — プレビュー停止と保持期間の短縮

Vercel の Hobby プランでデプロイメントストレージの上限 10 GB を超えました。原因はビルド1回 147 MB × 30日間で 189 回というデプロイ回数でした。

黒いカードに白のVercelの三角ロゴとロゴタイプ
目次

はじめに

Vercel の使用状況ページで、Deployment Storage に赤いリングが付いていました。無料枠 10 GB に対して 13.96 GBが使われています。他の項目はどれも上限の 20% に届いていません。

「Exceeded free resources」と題された Vercel の使用状況パネル。Deployment Storage が 10 GB 中 13.96 GB で赤いリング、Functions Storage が 10 GB 中 2 GB、Edge Requests が 1M 中 45K、Speed Insights Events が 10K 中 267 と表示されている

最初に気になったのは、公開中のサイトに影響が出るかどうかでした。影響はありませんでしたが、超過したままにすると代償はあります。Vercel は 30 日の保持期間を適用しなくなり、対象のデプロイを即座に削除しますし、上限を下回るまで新しいデプロイを拒否することもあります。

まず疑ったのはリポジトリでした。この記事も含めて、どの記事にも図やスクリーンショットが入っています。しかしリポジトリはパック後で 9.79 MiB、画像と動画を全部足しても 9.4 MB です。このサイトのビルド1回分は 147 MB で、それが 30 日間に 189 回作られていました。

プレビュービルドを止め、保持期間を1日に縮め、リリースフローの先頭に整理を1手入れたところ、同じグラフが 20.27 MB になりました。

クォータの読み方: ビルド 147 MB 対リポジトリ 9.79 MiB

Deployment Storage が測っているのはデプロイごとに保持されるビルド出力で、このサイトではそれを生成したリポジトリの約 15 倍あります。

どちらもコマンド1本で出ます。

ターミナルウィンドウ
入力
git count-objects -vH | grep size-pack
出力
size-pack: 9.79 MiB
ターミナルウィンドウ
入力
du -sm .vercel/output
出力
147 .vercel/output

クォータが数えているのは後者です。.vercel/output は vercel build が生成し vercel deploy --prebuilt がアップロードするもので、デプロイ側のファイル数は 2847、ローカルは 2843 で、転送中に実質的なものは増えていません。

147 MB の内訳

デプロイの半分はサーバーバンドルで、そのうち 20 MB は同じバンドルをもう一度収めたものです。

このサイトのビルド1回分をディレクトリ別に見る横棒が5本、サイズに比例して上から順に並ぶ。functions/_render.func の 54 MB、_functions の 20 MB、static/_astro の 33 MB、3言語分の HTML ディレクトリ合計 31 MB、static/pagefind の 3.7 MB。区切り線の下には、パック後のリポジトリ 9.79 MiB がはるかに短い棒で示されている。デプロイ1件 147 MB のうち、上位5ディレクトリfunctions/_render.funcAstro のサーバーバンドル。うち 29 MB が node_modules54 MB_functions/同じサーバービルドの2つ目のコピー20 MBstatic/_astro生成された画像派生ファイル 893 個33 MBstatic/ja + zh-tw + blog3言語分のレンダリング済み HTML31 MBstatic/pagefind検索インデックス3.7 MBgit count-objectsこれを生成したリポジトリ(パック後)9.79 MiB
このサイトのビルド1回分をディレクトリ別に見たもの。サーバーバンドルが2回現れ、static/_astro は3言語分の画像派生ファイル 893 個です。

_render.func の中には 29 MB の node_modules が入っています。Astro のサーバーランタイムと、記事ページがレンダリング時に読み込むもの一式です。static/_astro は Astro が処理済み画像を書き出す場所で、893 個という数は同じ元画像から作られた3言語分の派生ファイルです。

画像を外部に移しても 6% にしかならない理由

このリポジトリにコミットされている画像と動画は合計 9.4 MB です。オブジェクトストレージに逃がしても、デプロイ1回分の 16 分の 1 にしか効きません。

ターミナルウィンドウ
入力
find src -type f \( -name '*.mp4' -o -name '*.png' -o -name '*.jpg' -o -name '*.webp' -o -name '*.avif' \) -exec du -ch {} + | tail -1
出力
9.4M total

クォータが数えているのは static/_astro の方で、その派生ファイルはビルド時に元画像から生成されます。元画像をバケットから配信しても、git から 9.4 MB が出ていくだけで、33 MB の派生ファイルはそのまま残ります。

147 MB を半分にしたところで、占有する容量はデプロイ回数に応じて積み上がり続けます。デプロイ1回あたりのサイズを管理しても、問題は解決しません。

30 日間で 189 回のデプロイ

ストレージはビルドサイズ × デプロイ回数で、誰も見ていなかったのは回数の方でした。

ビルドサイズ × デプロイ数と Hobby プランの上限2つの箱を掛け合わせる。ビルド1回あたり 147 MB と、30日間で 189 件のデプロイ(うちプレビュー 122 件、本番 67 件)。その積は 27.8 GB。下には同じ尺度の棒が2本あり、27.8 GB と Hobby プランの上限 10 GB を比較していて、3倍近く超過している。クォータを埋めるもの147 MBビルド1回あたりvercel deploy がアップロードする分×18930日間のデプロイ数プレビュー 122 件、本番 67 件=27.8 GB1か月で消費した量作成された量27.8 GBHobby プランの上限10 GB10 GB
クォータを埋める積。目に見えるレバーは 147 MB の方でしたが、実際に効いていたのは 189 という数字です。

GitHub はデプロイごとに記録を残すので、回数は Vercel ではなくリポジトリ側から取れます。

ターミナルウィンドウ
gh api "repos/<owner>/<repo>/deployments?per_page=100" --paginate

直近 30 日を作成者別に集計すると、vercel[bot] が Preview 環境に作ったものが 122 件、このリポジトリの CI が production に作ったものが 67 件でした。

1回 147 MB として、189 回のデプロイは 10 GB の枠に 1 か月で 27.8 GB を流し込んだことになります。

誰も開かなかったプレビュー 122 件

デプロイの3分の2は、すでにマージされて削除されたブランチのプレビューでした。そしてそのすべてが自動で作られたものです。

超過した時点でまだ残っていた4件が理由を示しています。どれもそのブランチの最新プレビューで、どのブランチも squash マージ後に削除済み、git ls-remote --heads origin にはひとつも出てきません。

Vercel はアクティブなブランチの最新プレビューを残す仕様ですが、これらのブランチがすでに消えていることは把握していませんでした。

プレビュー停止、保持期間の短縮、そして整理

設定は3つで、それぞれ積の別の項に効きます。デプロイが作られる頻度、保持される期間、そしてすでに溜まっている数です。

Git 連携を止める

Vercel の Git 連携は、デフォルトでは push のたびに、ブランチを問わずデプロイを1件作ります。そのデプロイ1件ごとに Deployment Storage を 147 MB 占有します。

このサイトにそれらは必要ありません。本番は GitHub Actions がデプロイしており、他のブランチのデプロイも要らないからです。

vercel.json
{
"git": {
"deploymentEnabled": false
}
}

これで main を含むすべてのブランチについて、Git 連携が自前で作るデプロイが止まります。

保持期間は Project Settings のドロップダウン4つ

保持期間の設定は Vercel のダッシュボード、Project Settings の Build and Deployment にある Deployment Retention Policy にあります。このアカウントのプロジェクトはどれもプランの初期値のままでした。

デプロイの種類変更前変更後
Canceled30 日1 日
Errored30 日1 日
Pre-Production30 日1 日
Production30 日1 日

30 日は Hobby プランの最大値なので、初期値がそのまま一番削除の遅い設定でもあります。4つとも最短に変更しました。

Vercel の Deployment Retention Policy パネル。Canceled Deployments、Errored Deployments、Pre-Production Deployments、Production Deployments の4つのドロップダウンがいずれも「1 day」になっている

プレビューを受け持つのは Pre-Production Deployments の行です。保持するデプロイ件数を指定する項目はここにはありません。

Hobby プランでは vercel usage から何も読めません。

ターミナルウィンドウ
入力
pnpm dlx vercel@58 usage
出力
Error: Billing cost data is unavailable for 2026-09-01 through 2026-09-21.

Hobby プランには課金記録がないので、CLI には読むものがありません。GB の数字はダッシュボードにしか存在しません。

--safe が守るものと、消すもの

vercel remove <project> --safe はデプロイを消します。--safe を付けない同じコマンドはプロジェクトを消します。

ターミナルウィンドウ
入力
pnpm dlx vercel@58 remove oharu-tech-blog --safe --yes
出力
> Found 8 deployments for removal in oharu121s-projects [1s]
> Success! Removed 8 deployments [909ms]

--safe はエイリアスを持つデプロイを対象外にするので、ブランチのエイリアスを持ったままのプレビュー4件も一緒に残りました。

このプロジェクトの整理は2回に分かれるタイルが3列に並ぶ。実行前はデプロイ 13 件で、稼働中の本番が 1 件、ブランチのエイリアスを持つプレビューが 4 件、エイリアスなしが 8 件。vercel remove --safe を実行するとエイリアスなしの 8 件が消えて 5 件が残る。--safe はエイリアスを持つものをすべて残すため。次に URL を指定して削除すると、稼働中の本番 1 件だけが残る。2回に分かれる理由: --safe は本番以外も残す実行前デプロイ 13 件vercel remove --safeエイリアスなし 8 件を削除URL 指定で削除取り残されたプレビュー 4 件を削除→→稼働中の本番。ドメインのエイリアスを持つブランチのエイリアスを持つプレビュー。ブランチは削除済みエイリアスなし
--safe が消した8件と、残した4件。プレビューのブランチエイリアスは、指している当のブランチより長く生き残るので、2回目はデプロイを個別に指定します。

このプロジェクトにあった 13 件のうち、1回目で8件が消えて5件残りました。稼働中の本番デプロイと、すでに存在しないブランチのエイリアスを持ったままのプレビュー4件です。この4件は git ls-remote で確認してから URL 指定で消しました。

ターミナルウィンドウ
入力
pnpm dlx vercel@58 remove <url> <url> <url> <url> --yes
出力
> Found 4 deployments for removal in oharu121s-projects [934ms]
> Success! Removed 4 deployments [731ms]

リリースのどこで整理するか

整理はリリースの先頭で走らせます。末尾で走らせると、本番が変わったその瞬間に、ロールバック先になるはずのデプロイを消してしまうからです。

デプロイ前に整理すればロールバック先が残り、後で整理すると消える同じリリースのタイムラインが2本。1本目は検証とビルド、デプロイの前に整理を行い、直前の本番デプロイはデプロイ後のロールバックしたくなる期間まで残る。2本目はデプロイの後に整理を行い、その期間が始まる瞬間に同じデプロイが削除される。同じリリースを、前で整理する場合と後ろで整理する場合ロールバックしたくなる期間先に整理する整理検証とビルドデプロイ直前の本番デプロイ残っている後で整理する検証とビルドデプロイ整理直前の本番デプロイ削除済み
デプロイ前に整理すれば、ロールバックが必要になりやすい区間のあいだ、直前の本番デプロイが残ります。後で整理すると、まさにその瞬間に消えます。

13.96 GB から 20.27 MB へ

Vercel の Deployment Storage 合計を示す 30 日分の折れ線グラフ。7 GB 弱から始まり、9月8日ごろに約 17 GB まで上がり、9月21日には 14 GB まで下がったあと、9月22日に合計 20.27 MB まで垂直に落ちている

右端の垂直な落下が整理です。その手前の傾きは、30 日かけて積み上がった 189 回のデプロイです。

この数字は、3つをまとめて実施した結果です。Git 連携の自動デプロイを止め、保持期間を4種類とも1日にし、溜まっていた分を vercel remove で消しました。

まとめ

デプロイメントストレージはビルドサイズ × デプロイ回数で、読み違えやすいのは回数の方です。このアカウントには 10 個のプロジェクト、稼働中のデプロイ 185 件、147 MB のビルドがあり、リポジトリは合計に影響しないほど小さいものでした。

ストレージの問題かリポジトリの問題かは、3つの確認で分かれます。du -sm .vercel/output がデプロイ1件のサイズを出し、プラットフォーム側のデプロイ記録が回数を出し、その積を枠と突き合わせれば、デプロイを小さくするのか回数を減らすのかが決まります。

回数が問題なら、設定は3つです。新しく作られる分を止めるのが git.deploymentEnabled: false、古い分を落としていくのが保持ポリシー、すでに溜まった分を消すのが vercel remove --safe。今日その場で空くのは最後の1つだけで、しかもそれはリリースの末尾ではなく先頭に置くものです。

参考リンク

この記事をシェア