Frameworks · · 9 min read

Next.js image optimization outside Vercel: your options in 2026

What next/image does when you leave Vercel: the built-in resizer under next start, custom loaders for Bunny or imgproxy, Cloudflare Images, and hosts that skip resizing.

Outside Vercel, next/image still resizes images as long as your app runs with next start: the Next.js server does the work itself, at request time, and keeps the results in a disk cache. If your host doesn't run a Node.js server, or you'd rather not spend server CPU on images, you point next/image at a separate service with a custom loader, such as Bunny Optimizer, a self-hosted imgproxy or Cloudflare Images. On hosts that run Next.js on V8 isolates without an image service, including Eurobase, images are served at their original size, so you resize them before you deploy.

Ways to optimize Next.js images at a glance

PlatformWhere the resizing happensCostFits when
Your own Next.js serverInside next start, on the same machine that renders pagesServer CPU, memory and diskYou run a container or server, for example on Sliplane or Coolify on Hetzner
Bunny OptimizerOn Bunny's CDN, through a custom loader$9.50 a month per website, CDN bandwidth extraYou want a flat price and a European company
imgproxyOn a server you run, through a custom loaderFree open-source version, plus the serverYou want images to stay on your own infrastructure
CloudflareCloudflare Images, through OpenNext or a custom loader5,000 unique transformations a month free, then $0.50 per 1,000You already run on Cloudflare
EurobaseNowhere on the platform: images are served at their original sizeFlat €10 or €20 a month + VAT for the workspaceYou resize images during or before the build, or add a loader
VercelVercel's image optimization, built inHobby includes 5,000 transformations a month, on-demand from $0.05 per 1,000You stay on Vercel and an EU company isn't required

Prices are from each provider's own page, checked on 10 November 2026.

How the default works

When you write <Image src="/hero.jpg" width={800} height={400} />, Next.js doesn't link to /hero.jpg. It writes a srcset of URLs such as /_next/image?url=%2Fhero.jpg&w=828&q=75, and the browser picks one. Each of those URLs is a request to your own server, which fetches the original, resizes it, converts it and returns it.

The Next.js docs spell out the details you'll meet when you self-host:

  • Formats. The default output is WebP. You can add AVIF in images.formats, and Next.js picks the format from the browser's Accept header, so a proxy or CDN in front of your app must forward that header.
  • Cache. Optimized images are written to disk. By default Next.js checks free disk space at startup and uses up to 50% of it, and maximumDiskCacheSize sets a limit in bytes.
  • Expiry. minimumCacheTTL defaults to 14,400 seconds, or 4 hours. There's no way to invalidate the cache, so you change the src or delete .next/cache/images yourself.
  • Static export. output: 'export' has no server to resize anything, so you need a custom loader or unoptimized.

What to check on your host

  • Does it run `next start`? If yes, the built-in optimizer works with no configuration. If the host converts your app to another runtime, check its docs for images.
  • Where the disk cache lives. A container that restarts or scales out starts with an empty image cache on each instance, so the first visitors pay for the resizing again.
  • Who pays for the CPU. Resizing a large photo takes real CPU time. On a small server, a page full of new images competes with page rendering.
  • Which origins are allowed. remotePatterns and localPatterns decide which images your server will fetch and resize. Keep them narrow, or anyone can make your server process their images.

1. Your own Next.js server

The simplest answer is to keep using the built-in optimizer by running next build and next start in a container or on a server. Sliplane, for example, runs Next.js that way on a fixed-price server, and Coolify gives you a deploy interface on a machine you rent yourself. A small Hetzner cloud server starts at €5.49 a month excl. VAT for a CPX02 in Helsinki, or €6.49 in Falkenstein or Nuremberg, but on 10 November 2026 those cheapest plans showed as unavailable to order.

  • Best for: apps with a moderate number of images and a server that has spare CPU and disk.
  • Price: whatever the server costs. There's no charge per transformation.
  • What it lacks: a shared cache. Each instance keeps its own copies on its own disk, and they're lost when the instance is replaced.

2. Bunny Optimizer with a custom loader

Bunny is run by BunnyWay d.o.o., based in Ljubljana, Slovenia. Its Optimizer resizes, crops and converts images when you add parameters such as ?width=500&quality=75 to a URL served through a Bunny pull zone, then caches the result on its CDN. A Next.js custom loader returns that URL for each width.

  • Best for: teams that want resizing off their own server at one fixed monthly price.
  • Price: $9.50 a month per website, or per pull zone in Bunny's docs, with unlimited transformations. CDN bandwidth is billed separately. There's a 14-day free trial.
  • What it lacks: an entry in the Next.js list of example loaders, so you write the few lines yourself and test them.

3. imgproxy on your own infrastructure

imgproxy is a standalone image server written in Go on top of libvips, under the Apache 2.0 licence. It ships as Docker images and Linux packages, resizes and converts to WebP, AVIF and other formats from URL parameters, and works with your own storage.

  • Best for: teams that don't want image data to pass through a third party.
  • Price: the open-source version costs nothing, and a closed-source Pro version adds more features. Your only fixed cost is the machine that hosts it.
  • What it lacks: a managed service. Scaling, caching in front of it and updates are your job.

4. Cloudflare Images

OpenNext's Cloudflare adapter can answer /_next/image requests with Cloudflare Images once you add an IMAGES binding, or you can use a custom loader that builds /cdn-cgi/image/ URLs. OpenNext notes that minimumCacheTTL isn't supported there and that only PNG, JPEG, WebP, AVIF, GIF and SVG are optimized.

  • Best for: apps already deployed on Cloudflare Workers.
  • Price: the free plan covers 5,000 unique transformations a month, after which new ones fail with an error until you buy the paid plan at $0.50 per 1,000 beyond the first 5,000.
  • What it lacks: minimumCacheTTL, and for images that aren't static it ignores the Cache-Control header apart from marking them immutable.

5. Eurobase

On Eurobase, your Next.js app is built with OpenNext during deployment and served from V8 isolates. The platform sits on European infrastructure run by Scaleway, a French provider, and the company behind it is registered in Warsaw, Poland. next/image keeps working, but each image is served at its original size and nothing is resized on request. You can resize images before you commit them, generate sizes during the build, or try a custom loader that points at an image service, since the loader only changes the URLs written into the page. There's no Eurobase guide for loaders yet, so test one on a deployment first.

  • Best for: sites whose images are known at build time, such as marketing pages, docs and blogs.
  • Price: a Free plan, then €10 or €20 a month + VAT for the workspace. There are no usage charges today: work over a limit is refused, apps on V8 isolates and Functions stop until the monthly reset, and containers and static sites keep serving.
  • What it lacks: on-request resizing, preview deployments and a managed Postgres database. ISO 27001 and SOC 2 certification are in progress, not yet held.

6. Vercel

Vercel runs image optimization for you with no setup. You pay for transformations on each cache miss, plus cache reads and writes.

  • Best for: teams that want every next/image feature with nothing to run.
  • Price: Hobby includes 5,000 transformations, 300,000 cache reads and 100,000 cache writes a month. On-demand transformations cost $0.05 to $0.0812 per 1,000, depending on the region. When a Hobby team goes over, new images fail with a 402 error.
  • What it lacks: an EU company. Read EU region vs EU company.

How to choose

  • Keep next start on your own container if you already run one and your image volume is modest.
  • Add Bunny Optimizer or imgproxy through a custom loader when resizing starts to slow page rendering or your cache keeps emptying.
  • Use Cloudflare Images if your app already runs on Cloudflare.
  • Use Eurobase when your images are known at build time and you want a flat price on European infrastructure.

For the wider hosting question, see Next.js hosting in Europe. To move an app, follow Migrate from Vercel.

Frequently asked questions

Does next/image work without Vercel?

Yes. With next start, the Next.js server resizes and converts images itself, and the docs say this needs no configuration. On a static export or a runtime without the built-in optimizer, you add a custom loader or set unoptimized.

Why are my Next.js images slow or using lots of memory on my server?

Every new size of every image is resized by the same process that renders your pages, and the result is cached on local disk. A fresh container has an empty cache, so the first requests are slow. On glibc-based Linux, Next.js warns that optimization may need extra settings to limit memory.

How do I clear the Next.js image cache?

There's no invalidation API. Change the image's src, for example with a version in the file name, or delete .next/cache/images on each server.

Can I use an external image CDN with Next.js?

Yes. Set loader: 'custom' and loaderFile in next.config.js, and export a function that returns the CDN's URL for a given src, width and quality. The Next.js docs include example loaders for over a dozen services.

Does Eurobase resize Next.js images?

No. next/image works, but images are served at their original size, so resize them before or during the build.

Sources

Deploy your app in Europe

Sign up