vercel-bandwidth-egress-costs.html
< BACK Vercel 带宽账单:如何避免意外费用 -- 线条艺术插画

Vercel 带宽账单:如何停止意外收费

去年一个周一早上,一个客户给我打了个电话。不是短信。是电话。这从不是好兆头。他在上周四在 Vercel Pro 计划上部署了一个 Next.js 营销网站,在周末进行了产品发布,醒来后发现收件箱里有一张 340 美元的账单。网站效果很好。流量激增。Vercel 悄悄地计量了离开他们网络的每一 GB 数据。他没有设置支出上限。没有配置警报。什么都没有。

那通电话是我现在在与每个客户部署任何生产级代码之前花二十分钟进行 Vercel 账单卫生工作的原因。

以下是你需要了解的关于 Vercel 如何收取带宽费用、为什么它会令人措手不及,以及你实际上应该如何处理的内容。

---

Vercel 上的"出口流量"实际上是什么意思

Egress 是从 Vercel 网络传输到最终用户的数据。每一张图片、每一个 JavaScript 包、每一个 API 响应、每一个字体文件。如果它离开他们的边缘节点并到达浏览器,就会被计入。out of Vercel's network to the end user. Every image, every JavaScript bundle, every API response, every font file. If it leaves their edge and hits a browser, it counts.

Hobby 计划每月包含 100GB 带宽。Pro 是 1TB。听起来很多。但关键是:如果你在提供大型图片、在有繁重 JSON 负载的页面上进行服务端渲染,或者你的应用突然流量激增,你可能比想象中快得多就超过 1TB。截至本文撰写时,Vercel 对 Pro 计划超额部分按 $0.15/GB 收费(始终检查他们的当前定价页面,因为这个价格会变动)。their current pricing page because this moves).

所以超出限额 500GB 需要支付 $75。不是灾难性的。但一个病毒式传播时刻、一个失败的图片优化设置,或者一个爬虫疯狂打击你的 API 路由?那可能是几千块钱。

为什么这会让人措手不及

问题是,本地开发没有任何提示。你快速构建、快速部署,一切看起来都很好。Vercel 的仪表板显示带宽使用情况,但不会对你大声警告。如果你没有主动设置账单提醒,直到发票到达时才会发现。

---

最有可能破坏你账单的配置

我在 Seahawk 审计过很多部署。我一次又一次看到四个罪魁祸首。

1. 未优化的图片绕过 next/image

next/image 在它的功能上做得真的很好。它调整大小、转换为 WebP 并进行缓存。但我见过一些项目,开发者直接从指向 S3 桶中全分辨率文件的 <img> 标签中拉取图片,通过 Vercel API 路由代理。每个请求都在通过 Vercel 的网络拉取 4MB 的 JPEG,而不是从 CDN 边缘拉取 200KB 的 WebP。乘以 50,000 次页面浏览,算一下数学。 is genuinely good at what it does. It resizes, converts to WebP, and caches. But I've seen projects where developers were pulling images straight from an <img> tag pointing at full-resolution files in an S3 bucket, proxied through a Vercel API route. Every request was pulling a 4MB JPEG through Vercel's network instead of a 200KB WebP from a CDN edge. Multiply that by 50,000 page views and do the maths.

始终使用 next/image 并配置正确的 remotePatterns。如果图像源来自外部,确保它命中 CDN 缓存,而不是通过你的无服务器函数进行往返。next/image with a proper remotePatterns config. If the image source is external, make sure it's hitting the CDN cache and not making a round trip through your serverless functions.

2. 返回大型负载的 API 路由

2021 年我为一家英国零售商构建了电商产品目录。他们的 API 路由从数据库获取产品列表并返回整个产品对象,包括前端从未使用过的字段。描述、内部 SKU 备注、变体元数据等应有尽有。每个响应大约 80KB,而实际上只需要 12KB。entire product object, including fields the front end never used. Description, internal SKU notes, variant metadata, the lot. Each response was around 80KB instead of the 12KB it needed to be.

精简你的 API 响应。只返回客户端实际使用的字段。如果你使用 Prisma,用 select 来限制你拉取的内容。如果你使用第三方 API,在发送到下游之前转换并精简负载。select to limit what you pull. If you're using a third-party API, transform and slim the payload before sending it downstream.

3. 高流量路由上使用短重新验证窗口的 ISR

增量静态再生在理论上很棒。实际上,如果你在每分钟获得 10,000 次点击的页面上设置 revalidate: 30,你仍然可以正确缓存。但如果你设置 revalidate: 1 是因为你想要近实时更新而忘记改回来...你基本上是在用额外的步骤做 SSR,并在每次近似缓存未命中时为出站流量付费。revalidate: 30 on a page that gets 10,000 hits per minute, you're still caching correctly. But if you set it to revalidate: 1 because you wanted near-real-time updates and forgot to change it... you're basically doing SSR with extra steps and paying for the egress on every near-miss cache response.

明确设置你的重新验证窗口。大多数内容不需要每秒重新验证。

4. 没有缓存标头的无服务器函数

这个很微妙。如果你的无服务器函数响应不包含 Cache-Control 标头(或 Vercel 的 s-maxage / stale-while-revalidate 组合),响应不会在边缘缓存。每个请求都会命中该函数并进行完整往返。你完全失去 CDN 优势并为每个响应支付出站流量费用。Cache-Control header (or Vercel's s-maxage / stale-while-revalidate combo), the response is not cached at the edge. Every request hits the function and travels the full round trip. You lose the CDN benefit entirely and pay egress on every single response.

`` Cache-Control: s-maxage=3600, stale-while-revalidate=86400 `` Cache-Control: s-maxage=3600, stale-while-revalidate=86400 ``

仅这个 header 就为客户省了不少真金白银。说真的。Vercel 自己的缓存文档详细解释了 header 的行为。好好读一遍。Vercel's own caching docs explain the header behaviour in detail. Read them once properly.

---

如何设置账单告警(在你需要它们之前)

这应该是任何生产部署前的第一步。不是第七步。

  1. 前往你的 Vercel 团队设置。
  2. 在"账单"下,找到"支出管理"。Billing , find Spend Management.
  3. 设置支出限额(硬限制,Vercel 在超过限额后停止提供请求)或通知阈值(软告警,当你达到某个数字时发送邮件)。spend limit (hard cap, where Vercel stops serving requests after the limit) or a notification threshold (soft alert, emails you when you hit a number).
  4. 我建议在你认为难以接受的金额的 50% 处设置通知,在预期月账单的约 120% 处设置硬限制。

硬限制是把双刃剑。如果触发了,你的站点就会宕机。所以要仔细考虑。对于营销站点?没问题,硬性限制。对于有付费用户的 SaaS?设置宽松的通知,改为监看仪表板。

---

将重负荷工作转移到其他地方

Vercel 不是静态资产的 CDN。我是说,它有 CDN,但你要按 GB 付费。对于大量静态资产,把它们放在更便宜的地方。

过去十八个月我一直通过 Cloudflare R2 路由大型媒体文件。R2 没有出站费。你只为存储和操作付费,不为流出的数据付费。对于图片密集型网站来说,这能节省一大笔钱。我的一个客户运营的摄影作品集平台之前在 Vercel 出站费上要花大约 $180/月。我们把所有全分辨率图像和图库资产移到了 R2,保留缩略图通过 next/image 传输,Vercel 账单就降到了 $40 以下。Cloudflare R2 for about eighteen months now. R2 has zero egress fees. You pay for storage and operations, not for the data going out. For image-heavy sites this is a serious saving. A client of mine runs a photography portfolio platform and was paying around $180/month in Vercel egress. We moved all the full-res images and gallery assets to R2, kept the thumbnails going through next/image, and the Vercel bill dropped to under $40.

值得了解的替代方案:

  • Cloudflare Pages,用于静态部署且你不需要 Vercel 边缘特性的情况。慷慨的免费层,没有出站费。 for static deployments where you don't need Vercel's edge features. Generous free tier, no egress fees.
  • AWS CloudFront 配合 S3,如果你已经在 AWS 生态系统中。大规模情况下转移成本比 Vercel 的超额费率更低。 in front of S3 if you're already in the AWS ecosystem. Transfer costs are lower than Vercel's overage rates at scale.
  • BunnyCDN 价格便宜,用于纯资产传输速度快。我在几个资产量很大的 WordPress-to-Next.js 迁移项目中用过它,都是高流量场景。 is cheap and fast for pure asset delivery. I've used it on a few high-traffic WordPress-to-Next.js migrations where the asset volume was large.

重点是:Vercel 是运行 Next.js 应用逻辑的合适地方。它不总是传输你的 GB 级媒体的合适地方。

---

实时监控使用情况

不要只在月底查看仪表板。这就是我的一个客户最后在周一给我打电话的原因。

我实际使用的几个工具:

  • Vercel Analytics 提供页面级数据,对于发现哪些路由产生最多流量(因此也产生最多出站流量)很有用。 gives you page-level data and is useful for spotting which routes are generating the most traffic (and therefore the most egress).
  • Axiom 与 Vercel 的日志导出集成得很好,让你可以查询一段时间内的请求大小。我从 2022 年末开始使用它,对于关联流量峰值和出站流量跳跃来说,它在较大项目上一直很有用。 integrates cleanly with Vercel's log drains and lets you query request size over time. I started using it in late 2022 and it's been useful on bigger projects for correlating traffic spikes with egress jumps.
  • 设置一个简单的 cron(Vercel 现在原生支持 cron)来调用他们的 API,当带宽超过阈值时发送信息到 Slack 频道。我为 Seahawk 自己的基础设施构建了一个轻量级版本。花两小时,省去很多焦虑。

Vercel REST API 公开了部署和使用数据。这不是世界上最优雅的 API,但它能满足基本告警的需求。Vercel REST API exposes deployment and usage data. It's not the most elegant API in the world but it does what you need for basic alerting.

---

没人谈论的架构决策

这是我看到讨论不够的一个问题:有时候 Vercel 不是正确的默认选择。

如果你的项目是一个没有真正动态功能的静态营销网站,你不需要 Vercel。Cloudflare Pages 或 Netlify 的免费层可以胜任工作,完全无出站流量问题。你不是在"浪费" Vercel,只是没有为工作负载选对工具。

反过来说,如果你在构建一个真正的 Next.js 应用,使用边缘中间件、服务器组件和执行实际工作的 API 路由,Vercel 就值得付费。开发者体验确实优秀,边缘网络速度也快。只要从一开始就架构得当。

我职业生涯早期犯的错误(2016 年左右,那时 Vercel 还不存在,我在摸索 Heroku 和 Netlify 的部署方式)是把部署平台当作免费的事后处理。平台选择对你的成本结构的影响,和数据库选择一样大。认真对待它。

---

常见问题

Hobby 计划超过 100GB 会产生出站流量费用吗?

不会。Hobby 计划上 Vercel 不会对超额部分收费;一旦你达到限制,他们会降速或暂停部署。两种情况都不太理想,但你不会收到意外账单。意外账单发生在 Pro 和 Enterprise 计划上,这些计划会对超出包含额度的使用量计费。

Vercel 的图片优化会计入出站流量吗?

会。通过 next/image 提供的优化图片仍然计入出站流量。节省的是文件大小:你提供的是 180KB 的 WebP 而不是 3MB 的 JPEG,所以每张图片的出站流量要低得多。优化本身才是降低成本的原因,不是什么特殊豁免。next/image still count as egress. The saving is in file size: you're serving a 180KB WebP instead of a 3MB JPEG, so the egress per image is much lower. The optimisation itself is what reduces the cost, not some special exemption.

我能在 Vercel 前面使用自定义 CDN 来降低出站流量吗?

你可以把 Cloudflare 的代理放在 Vercel 部署的前面。Cloudflare 在其边缘节点缓存响应,这意味着命中 Cloudflare 缓存的请求根本不会到达 Vercel。这能显著降低出站流量和函数调用次数。预览部署和请求头处理上有一些注意事项,但对于生产环境来说,这是一个常见且合理的做法。Cloudflare 关于代理的文档涵盖了设置方法。Cloudflare's documentation on proxying covers the setup.

Vercel 账单意外激增的最大单一原因是什么?

根据我的经验:图像处理。要么是未经优化就直接提供全分辨率图像,要么是图像优化路由在每次请求时都被调用却没有正确缓存。先处理好你的图像管道,其他一切都是次要的。

Vercel 会在使用量激增时自动通知你吗?

默认情况下不会。你需要自己配置。没有开箱即用的告警能说"你已经用了 80% 的带宽"。这就是问题所在。在设置生产部署的同一天就配置好支出管理阈值。不要拖后。

---

Vercel 是一个很好的平台。我用它,Seahawk 也用它,我会继续为适合的项目推荐它。但它是一个运行在真实基础设施上的按量计费服务,定价反映了这一点。被意外账单伤害的开发者几乎总是那些把它当成免费 CDN 来用、从不查看账单设置的人。在部署时花五分钟配置,就能为你省去一个非常难熬的周一早晨的电话。

< BACK