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

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

- Source: https://oharu121.com/ja/blog/vercel-hobby-deployment-storage-previews-retention-prune/
- Published: 2026-09-24T14:05:22+09:00
- Tags: Vercel, 開発ツール, Claude Code

---
## はじめに

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

*Image: 「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本で出ます。

```bash
git count-objects -vH | grep size-pack
# size-pack: 9.79 MiB
```

```bash
du -sm .vercel/output
# 147	.vercel/output
```

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

### 147 MB の内訳

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

*Figure — BuildBreakdown: このサイトのビルド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 にしか効きません**。

```bash
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 回のデプロイ

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

*Figure — QuotaArithmetic: クォータを埋める積。目に見えるレバーは 147 MB の方でしたが、実際に効いていたのは 189 という数字です。*

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

```bash
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 がデプロイしており、他のブランチのデプロイも要らないからです。

```json title="vercel.json" ins={3}
{
  "git": {
    "deploymentEnabled": false
  }
}
```

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

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

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

| デプロイの種類 | 変更前 | 変更後 |
| --- | --- | --- |
| Canceled | 30 日 | 1 日 |
| Errored | 30 日 | 1 日 |
| Pre-Production | 30 日 | 1 日 |
| Production | 30 日 | 1 日 |

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

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

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

> **気を付けて**
>
> **保持期間は削除キューではありません**。ポリシーを設定すると削除対象になるだけで、削除そのものは起きません。このアカウントでは、稼働中のデプロイ 185 件のうち 148 件がすでに 30 日の保持期間を過ぎたまま残っていました。

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

```bash
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` を付けない同じコマンドはプロジェクトを消します**。

```bash
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件も一緒に残りました。

*Figure — TwoPassPrune: `--safe` が消した8件と、残した4件。プレビューのブランチエイリアスは、指している当のブランチより長く生き残るので、2回目はデプロイを個別に指定します。*

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

```bash
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回目のコマンドにプロジェクト名を渡すとプロジェクトが消えます**。2回目には `--safe` がなく、`vercel remove` にプロジェクト名を渡すと、デプロイもろともドメイン、環境変数、保存されたシークレットまで削除されます。ここに書いてよいのはデプロイの URL だけです。

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

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

*Figure — PrunePlacement: デプロイ前に整理すれば、ロールバックが必要になりやすい区間のあいだ、直前の本番デプロイが残ります。後で整理すると、まさにその瞬間に消えます。*

## 13.96 GB から 20.27 MB へ

*Image: 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つだけで**、しかもそれはリリースの末尾ではなく先頭に置くものです。

## 参考リンク

- [Vercel: Deployment Storage（何を計上するのかと保持の例外）](https://vercel.com/docs/deployment-storage)
- [Vercel: Optimize deployment storage](https://vercel.com/docs/deployment-storage/optimize)
- [Vercel: Git configuration（deploymentEnabled の真偽値形式とブランチ別形式）](https://vercel.com/docs/project-configuration/git-configuration)
- [Vercel changelog: Hobby projects now retain fewer deployments to free up storage](https://vercel.com/changelog/hobby-projects-now-retain-fewer-deployments-to-free-up-storage)
