你以为 GitHub Actions 的缓存只是存着?今天计费逻辑悄悄把这件事彻底变了

你有没有遇到过这种情况:矩阵构建跑完,缓存明明写进去了,下一个 job 却还是冷启动,一个 npm ci 跑了五分钟。查日志,job 没报错,缓存也”成功”写入了——但读不出来。直到你发现账单上 runner 分钟数比预期多了三倍,才发现真正的问题根本不是代码。

GitHub Actions 的缓存系统,2026 年的计量逻辑已经悄悄变了。

两个限制,不是你以为的一个

GitHub Actions 缓存有两套限制,大多数人只知道第一个:每个仓库 10 GB 免费额度,超出 $0.07/GB/月。这听起来很直接,用多少花多少。但第二个限制才是真正让人吃亏的——每分钟 200 次写入上限(rate limit),2026 年 1 月 16 日悄悄上线,官方文档里只出现在”限制”页面。

这个 rate limit 不是为了多收费,它的背景是”cache thrash”。Node.js 核心仓库和 Nix 社区的多个项目把 GitHub 的缓存后端打爆了——几十个 job 在同一个 60 秒窗口内同时写入新鲜缓存条目,所有人都在争同一个写入队列。GitHub 工程师直接在 issue 里帮忙排查,这说明这不是假设中的边缘场景,是真实的生产问题。

rate limit 失败不报错,这才是最坑的地方

当你触发 rate limit,缓存写入被拒绝——但你的 job 不会失败。它会正常结束,退出码是 0。日志里看起来一切正常,甚至会有”Cache not found”的提示。但真正受伤的是下一个需要读这个缓存的 job:它以为有暖缓存可用,结果 cache hit 是 false,乖乖跑了一次冷启动。

一次冷启动的 npm ci 在 Linux runner 上大约 2-5 分钟,在 Windows 上 5-15 分钟,在 macOS 上 10-30 分钟。按 2026 年 1 月调整后的费率:

系统 2核每分钟费用
Linux $0.006
Windows $0.010
macOS $0.062

一次被拒绝的缓存写入,导致后续 job 跑了 5 分钟冷启动,在 macOS runner 上烧掉 $0.31。而你那个 10 GB 存储超额的账单,按 $0.07/GB/月算,一个月超 5 GB 也才 $0.35——一次 macOS 上的缓存失效,等于白交一个月存储费。

bex.co 的分析里有个更极端的案例:monorepo 一次 PR wave,几十个 job 同时触发 rate limit,一整轮构建多烧掉的 runner 分钟费,轻松超过整月的缓存存储账单。存储费从来不是大头,rate limit 把你踢到 per-minute 计时器上,才是真正出血的地方。

GitHub 给的解法是让你多写代码

官方建议了两条路:实现指数退避(exponential backoff),或者升级你依赖的缓存 actions 让它能优雅处理 429 响应。这两条都是工程工作——你需要改 CI 配置、改依赖版本、测试退避逻辑。而做这些的目的,只是为了拿回一个 flat unmetered cache 本应免费给你的东西。

对于大多数中小团队来说,这个成本其实还没到需要折腾自托管 runner 的程度。真正值得花时间的是三件具体的事:

第一步:审计你的矩阵并发数。 一个 50-job 矩阵,同一秒内全部完成,理论上一分钟内向缓存写入 50 个条目。如果每个 job 写入多个缓存(node_modules + .turbo + 其他),触发 rate limit 只需要 4 个 job 同时跑完。打开 Actions 日志,搜 cache miss 或者计算每个 job 的缓存写入次数,你就能知道自己离上限还有多远。

第二步:合并缓存键,减少重复写入。 如果你的矩阵 job 里有大量重复的依赖路径(这在 monorepo 里很常见),可以先把公共依赖提到 job 外部单独缓存一次,再让矩阵 job 共享这个缓存。写入次数从 N 变成 1+n,rate limit 压力骤降。

第三步:给缓存读取失败加监控。 缓存命中率和 job 总耗时应该放进你的 CI 仪表盘。如果某天缓存命中率突然下降,同时总耗时上升,大概率是有人新加了 job 撞上 rate limit 了。等用户来报账单才发现,已经多烧了好几天钱了。

什么时候该考虑自托管

如果你的团队每天跑几百个矩阵 job,monorepo 体量巨大,已经在认真算 per-minute 账单了,那有一条彻底绕过这个问题的路:自托管 runner 配持久化 NVMe 卷。GitHub Actions 的缓存是多人共享的后端 API,你的写入会跟所有其他仓库争同一个队列;自托管 runner 的 NVMe 是本地磁盘,不存在多租户竞争,没有 per-GB 计费,也没有 rate limit。当然,这需要运维成本——机器要维护、容量要规划——这是一笔基础设施账,不是工程团队的日常账。

对于大多数团队,2026 年 GitHub Actions 缓存的正确认知应该是:它不是一个”存着就行”的免费空间,而是一个有写入上限、被 rate limit 默默计费的共享资源。知道这个规则,比多装几个缓存插件更重要。

评论区

0 条评论

登录后可评论。