MONII Guides Why is my Vercel bill so high?
Guide · Vercel billing

Why is my Vercel bill so high?

Vercel bills go wrong in a small number of specific ways. This walks through each one, how to identify it in your own usage, and what to do about it.

A Vercel bill goes wrong in a small number of specific ways. This page walks through each, in rough order of how often it is the culprit, with how to confirm it in your own usage.

If you are mid-incident and just want it stopped, skip to how to pause a Vercel project.

The short version

In most cases it is traffic you did not know you had — bots, AI crawlers or a scraper — hitting a route that bills per request, most often image optimization. The second most common is a build loop. Check the usage dashboard's per-project breakdown first; the outlier is usually obvious once you look.

1. Image optimization#

The most common cause of a bill that looks impossible relative to your traffic.

Every unique transformation is billable. Unique means the combination of source image, width, quality and format. A crawler that walks query-string variants of your image URLs generates a new billable transformation on every combination it tries — from a site with essentially no human visitors.

One widely-cited Hacker News thread on this reported two AI crawlers sending 66,500 requests in a single day, with the author noting that "$5 to resize 1,000 images is ridiculously expensive" when the images are being resized for bots.

How to confirm: usage dashboard → Image Optimization. If transformations are wildly out of proportion to page views, this is it.

What to do: - Set images.qualities and images.formats in next.config.js so the number of valid variants is bounded rather than open-ended. - Rate-limit or firewall image routes. Most bot traffic is unsophisticated and dies to a basic rule. - Consider serving pre-optimised static images for anything that does not genuinely need on-the-fly transformation.

2. Bandwidth, from traffic that is not human#

Bandwidth is billed on bytes out, and attack traffic bills at the standard rate. There is no discount for the fact that you did not want it.

The documented cases are stark: a $23,000 Vercel bill from a DDoS where every byte of attack traffic was billed normally; a $104,000 bill on what the author describes as a static site.

How to confirm: bandwidth far exceeding what your analytics say humans consumed. The gap is the answer.

What to do: Vercel's WAF and rate limiting, plus caching (see §7). If you are under active attack, pause the project first and reason about it afterwards.

3. Serverless function loops#

A retry without backoff, or two functions calling each other, and both invocation count and duration climb together. This is the fastest-moving failure mode on the list — it can do serious damage inside an hour.

How to confirm: invocations or GB-hours spiking with no matching traffic increase. Check for a function whose average duration has also jumped.

What to do: timeouts on every outbound call, exponential backoff on every retry, and a hard cap on retry attempts. If a function can call itself even indirectly, add a depth guard.

4. Build minutes, especially in a monorepo#

A documented Vercel Community case: a $602.21 bill of which $601.52 was build minutes, on a monorepo.

Monorepos are the classic trap. Without correct ignore rules, a change to one package rebuilds every project in the repo. Multiply by every push.

How to confirm: usage dashboard → Build. Compare build count against how many deploys you actually intended.

What to do: - Set ignoreCommand per project so unrelated changes do not trigger a build. - Turn off deploys for preview branches you never look at. - Check for a build that is retrying on failure in a loop.

5. Edge requests#

Billed per request, including requests that return 304, redirects, and middleware invocations. A site with aggressive client-side polling can rack these up quietly.

How to confirm: edge request count far exceeding page views.

What to do: longer cache lifetimes, and check whether middleware is running on routes it does not need to — including static assets.

6. Fast Origin Transfer#

The one people have never heard of. It bills data moving from your function or origin into Vercel's edge network — so an uncached response that pulls a large payload from a database on every request bills twice over, once here and once as bandwidth.

How to confirm: a Fast Origin Transfer line that is not near-zero.

What to do: cache. This line item is almost entirely a symptom of cache misses.

The good version of the problem. A post lands, and a plan sized for a quiet month meets a week that is not quiet.

Worth separating from the others because the response is different: this is a capacity conversation, not a bug hunt.

Finding out which one it was#

In the dashboard: usage page, filtered per project. Look for the line item that is disproportionate rather than the one that is largest.

On the command line: since February 2026 Vercel has a billing API and a vercel usage command:

vercel usage --from 2026-07-01 --to 2026-07-31 --breakdown daily --format json

It is genuinely useful for post-mortems — daily granularity, JSON out, up to a year of range. It is also entirely read-only. There is no watch mode, no threshold, no alert and no pause. It tells you what happened; it does not tell you what is happening.

Stopping it happening again#

Layer these — no single one is enough.

  1. Turn on Spend Management, including the pause. Note that it is Pro-only, and setting an amount does not by itself stop usage — the pause switch is separate and off by default. Enable both.
  2. Firewall and rate-limit the expensive routes: image optimization, anything touching a database.
  3. Cache aggressively. Long s-maxage on anything not per-user, plus stale-while-revalidate. This is the single biggest lever on every line item above.
  4. Bound your image variants in config.
  5. Watch usage somewhere you will actually see it. A threshold email lands in an inbox you check on weekday mornings. Runaway usage does not respect weekday mornings.
Where MONII fits

MONII covers point 5 and only point 5. It polls your Vercel and Netlify usage and pushes your phone when you cross a percentage you choose, then lets you pause the project from the notification. It is a second, independent alarm — it does not replace the firewall, the caching or Vercel's own spend controls, and it will not save you if those are not set up. It shortens the window between something going wrong and you knowing. That is the whole job.

Questions people actually ask

What is the most common cause of a surprise Vercel bill?

Image optimization and bandwidth driven by traffic you did not expect — usually bots, AI crawlers or a scraper. Every unique image transformation is billable, so a crawler walking query-string variants can generate thousands of them from a site with almost no human visitors.

Can I see which project is costing the most?

Yes. Vercel's usage dashboard breaks down by project, and since February 2026 there is a billing API and a vercel usage CLI command that can output JSON with daily granularity. Both are read-only after the fact — neither watches or alerts.

Will Vercel refund an unexpected bill?

Sometimes, at their discretion, particularly for clear-cut attack traffic. Several widely-shared cases have ended in partial or full forgiveness after a support conversation. Treat it as a goodwill outcome you might get, not a control you have.

Does the Hobby plan bill me?

No. Hobby is not usage-billed, so there is no bill to be surprised by. The Hobby risk is different: hitting a limit can suspend your projects until the cycle resets.

Find out during, not after

MONII watches Vercel and Netlify usage and pushes you the moment you cross a threshold you set — with a kill switch to pause the project.

Get MONII for iOS ›