把 Vercel 部署儲存空間從 13.96 GB 降到 20.27 MB — 關閉預覽、縮短保留期
Vercel Hobby 方案的部署儲存空間超過了 10 GB 上限。原因是由部署次數造成的:每次部署都會增加 147 MB,三十天內部署了 189 次。

本頁目錄
引言
Vercel 的用量頁面在 Deployment Storage 旁邊顯示了一個紅圈:免費額度 10 GB,用掉 13.96 GB。同一個帳戶裡,其他項目沒有一項超過上限的 20%。

我第一個想知道的是線上網站會不會受影響。答案是不會。不過一直超過上限還是有代價的:Vercel 會不再遵守 30 天的保留期,會直接刪掉符合條件的部署,也有可能在回到額度以內之前拒絕新的部署。
我一開始懷疑的是 repo,畢竟這裡每篇文章都帶著圖表和截圖。然而 repo 打包後只有 9.79 MiB,所有影像和影片加起來也才 9.4 MB。這個網站部署一次用掉的空間是 147 MB,而三十天內共部署了 189 次。
關掉預覽建置、把保留期縮到一天,並且在發布流程的開頭加上清理處理,最後成功讓 Deployment Storage 變成了 20.27 MB。
讀懂配額:一次建置 147 MB,repo 9.79 MiB
Deployment Storage 量的是每次部署所保留的建置產物,在這個網站上大約是 repo 本身的 15 倍大。
兩個數字各用一行指令就能拿到。
輸入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 分布在哪裡
每次部署有一半是伺服器 bundle,而這一半裡面有 20 MB 是它自己的第二份複本。
static/_astro 則是三種語系共 893 個影像衍生檔。_render.func 裡面有 29 MB 的 node_modules,也就是 Astro 的伺服器執行環境,加上文章頁在算繪時會引入的一切。static/_astro 是 Astro 寫出處理後影像的位置,那 893 個檔案,是同一批原始圖片在三種語系下產生的衍生檔。
把影像搬到外部為什麼只能省下 6%
這個 repo 裡所有影像和影片加起來是 9.4 MB,所以就算全部搬去物件儲存的 bucket,能省下的空間也只有一次部署的十六分之一。
輸入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,那些衍生檔是建置時從原始圖片產生的。把原圖改由 bucket 提供,只是把 9.4 MB 移出 git,33 MB 的衍生檔原封不動留在部署包裹裡。
就算我能夠把 147 MB 砍成一半,佔用 Deployment Storage 的空間還是會隨著部署次數一路疊加上去,因此管理單次部署的大小並非解決問題的關鍵。
三十天內 189 次部署
儲存空間等於建置大小乘以部署次數,而我之前從來沒去關注過部署次數這一項。
GitHub 會為每次部署留下紀錄,所以次數是從 repo 而不是從 Vercel 取得的。
gh api "repos/<owner>/<repo>/deployments?per_page=100" --paginate把最近三十天的紀錄依建立者分組,vercel[bot] 對 Preview 環境建立了 122 次,這個 repo 自己的 CI 對 production 建立了 67 次。
以每次 147 MB 計算,189 次部署等於一個月內往 10 GB 的額度裡灌進 27.8 GB。
沒人打開過的 122 個預覽
這些部署有三分之二是早已合併並刪除的分支所留下的預覽,而且每一個都是自動建立的。
留下來的四個部署,每一個都是某個分支的最新預覽。那些分支都已經在 squash 合併後被刪掉,git ls-remote --heads origin 一個也列不出來。
即使這些分支早已被刪除,Vercel 仍然保留了這些分支的最新預覽,而並沒有察覺這些分支已經不存在了。
關掉預覽、縮短保留期,再清理一次
三個設定,分別對著乘積裡的一項:部署被建立的頻率、被保留的時間,以及此刻還擺在那裡的數量。
關掉 Git 整合
Vercel 的 Git 整合預設會替每一次 push 都會建立一個部署,不分分支。因此每個部署都佔用 147 MB 的 Deployment Storage。
這個網站不需要那些自動部署:正式環境是由 GitHub Actions 部署的,其他分支的部署也都不需要。
{ "git": { "deploymentEnabled": false }}這會停掉包含 main 以及所有其他分支的 Git 整合所自動產生的部署。
保留期是 Project Settings 裡的四個下拉選單
保留期設定在 Vercel 的控制台,位於 Project Settings 的 Build and Deployment 底下,名稱是 Deployment Retention Policy。這個帳戶裡的每個專案都停在方案的預設值。
| 部署類型 | 變更前 | 變更後 |
|---|---|---|
| Canceled | 30 天 | 1 天 |
| Errored | 30 天 | 1 天 |
| Pre-Production | 30 天 | 1 天 |
| Production | 30 天 | 1 天 |
30 天是 Hobby 方案的上限,所以預設值同時也是最慢的那個設定。四項全部改成最短的值。

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 會跳過持有別名的部署,因此有四個持有分支別名的預覽也一起被留了下來。
--safe 刪掉的八個,和它放過的四個。預覽的分支別名活得比它指向的分支還久,所以第二次要逐一指名部署。十三個部署刪掉八個,剩下五個:線上那個正式部署,加上四個分支早就沒了的預覽。確認過分支真的不在之後,這四個只能用 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]清理該放在發布流程的哪裡
清理要放在發布流程的開頭。放在結尾的話,正式環境才剛換上新版本,舊的那個部署就被刪掉了,想回滾也沒得回。
從 13.96 GB 到 20.27 MB

我做了三件事讓 Deployment Storage 從 13.96 GB 降到了 20.27 MB:關掉 Git 整合的自動部署、把四種保留期都改成一天,再用 vercel remove 把堆積的部署清掉。
總結
部署儲存空間等於建置大小乘以部署次數,而比較容易判斷錯的是次數。這個帳戶有十個專案、185 個存活的部署、147 MB 的建置,而 repo 小到對總量沒有影響。
要分辨這是儲存空間的問題還是 repo 的問題,有三個檢查。du -sm .vercel/output 給出一次部署的大小,平台自己的部署紀錄給出次數,兩者的乘積對上額度,就能決定應該要把部署變小,還是要減少部署次數。
如果問題出在次數,我們能做三件事:關閉 Vercel 的自動部署: git.deploymentEnabled: false、縮短舊部署的保留時間,以及手動刪除已經不需要的舊部署: vercel remove --safe。能立竿見影的方法只有最後一個,而且我們應該把它放在整個發布流程的開頭,而不是結尾。

