Next.js image optimization on Vercel bills per unique transformation — one source image at one width and quality — not per page view or per byte served. The Pro plan includes 10,000 transformations monthly; a product catalog or image-heavy blog can exhaust that before traffic becomes the limiting factor.

Key takeaways

  • Transformations, not requests, are the billable unit. A cached, already-generated size costs nothing on repeat.
  • Responsive breakpoints multiply the count. Each width next/image serves for one source image is a separate transformation.
  • Catalogs exhaust the allowance faster than blogs. 500 products × 4 sizes is 2,000 transformations before any content publishes.
  • The unoptimized flag plus a third-party CDN sidesteps this entirely — at the cost of a second billing relationship.
  • Self-hosting doesn't remove the cost, it relocates it to your server's CPU.
Disclosure: some hosting links on this site are affiliate links, disclosed above the first such link on any page that contains one. This article compares costs and mechanics only — no provider is recommended over another here.

What counts as a billable transformation

Each unique combination of source image, requested width, and quality setting counts as one transformation the first time it is generated. Vercel's Pro plan includes 10,000 transformations per month; usage beyond that is billed as overage. Once a specific size has been generated, subsequent requests for it are served from cache at no additional transformation cost.

This matters because the unit isn't intuitive. A page view isn't the meter — the number of distinct image variants your site ever needs to generate is. A single hero image served at five responsive breakpoints is five transformations total, regardless of how many times it is viewed afterward. The exposure comes from breadth of unique images, not depth of traffic to any one of them.

Responsive breakpoint
One of the specific pixel widths next/image generates for a given source image, so the browser can request a size matched to the viewport instead of downloading one oversized file everywhere. Next.js typically generates several per image by default — each one is a separate transformation the first time it's requested.

Why catalogs and galleries exhaust the allowance fastest

Any site with many distinct images — a product catalog, a photo gallery, an image-heavy archive — multiplies transformation count by both image count and breakpoint count. A catalog of 500 products at 4 responsive sizes reaches 2,000 transformations before a single blog post publishes or any real traffic arrives.

Modelled transformation count by site type, before the 10,000/month Pro allowance is applied.
Site type Unique images Breakpoints served Total transformations Within Pro allowance?
Text-led blog, few images 150 3 450 Comfortably
Portfolio / photography site 800 4 3,200 Yes
Small e-commerce catalog 500 products 4 2,000 Yes, alone
Mid-size catalog + content growth 2,500 products 4 10,000 At the line
Large catalog, seasonal updates 6,000 products 4 24,000 140% over

Traffic is almost irrelevant to this number. A catalog with ten visitors a day and one with ten thousand generate the same transformation count on first render, because the cost event is creating each unique size once, not serving it repeatedly. This is the opposite of how most hosting costs scale, and it's why teams migrating a catalog to Next.js are frequently surprised by an image-optimization line item that has nothing to do with visitor volume.

Modelled monthly cost at three catalog sizes

Vercel's Pro plan includes 10,000 transformations in the base $20/month price. Beyond that, overage is metered separately from bandwidth. A catalog of 6,000 products at 4 breakpoints generates roughly 24,000 transformations — 14,000 over the included allowance — turning a $20 base plan into a materially larger bill before any traffic pricing is even applied.

  • Under ~2,500 unique images at 4 sizes: stays within the included 10,000 transformations. Base plan price only.
  • 2,500–5,000 unique images: approaches or crosses the line depending on breakpoint count. Worth checking before a catalog migration, not after.
  • Above ~5,000 unique images: overage becomes a real, recurring line item, separate from and additive to bandwidth costs already covered in the Next.js hosting cost comparison.
The multiplier people miss. Reformatting a catalog (new photography, a redesign, adding a size) regenerates transformations for every affected image again. A one-time catalog refresh can spike transformation usage in a single month even on a site whose steady-state usage was previously well within the allowance.

How to avoid or reduce the charge

Three practical options, in order of how much control they trade away.

  1. Pre-optimize and serve with unoptimized. Generate final sizes at build time or via an external pipeline, then set the unoptimized prop on next/image so Vercel never runs its own transformation step. You keep the component's layout/loading benefits without the metering.
  2. Route through a third-party image CDN. Services like Cloudinary or Imgix handle resizing and format conversion themselves; you point next/image's loader at their URLs instead. This removes Vercel's transformation billing but adds that service's own pricing and a second point of failure.
  3. Self-host and let the server do the work. On a VPS, image optimization consumes CPU rather than appearing as a metered line item. See the hosting pillar guide for when a VPS is the cheaper choice overall — the same "buys time, not always money" logic applies here.

Which option actually makes sense

  • Small site, few images: the default managed pipeline is fine — you'll likely never approach the allowance.
  • Growing catalog, staying on Vercel: model your transformation count before it grows, using the table above as the starting formula (images × breakpoints), and budget for overage rather than being surprised by it.
  • Large catalog, cost-sensitive: pre-optimize and serve with unoptimized, or move to a VPS where the cost becomes compute you already provisioned rather than a separate metered service.
This is a single line item inside a larger hosting decision. For the full monthly bill across managed, VPS and static hosting, see the Next.js hosting cost comparison or run your own numbers in the cost calculator.

Badri Dutta

Software engineer · 15 years building for the web

Fifteen years building for the web, including catalog-heavy Next.js projects where the image optimization bill was the surprise nobody had modelled ahead of time. This breakdown exists so the next migration doesn't repeat that.

Full background →