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

Last updated: 2026-11-10

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

| Platform | Where the resizing happens | Cost | Fits when |
|---|---|---|---|
| Your own Next.js server | Inside `next start`, on the same machine that renders pages | Server CPU, memory and disk | You run a container or server, for example on Sliplane or Coolify on Hetzner |
| Bunny Optimizer | On Bunny's CDN, through a custom loader | $9.50 a month per website, CDN bandwidth extra | You want a flat price and a European company |
| imgproxy | On a server you run, through a custom loader | Free open-source version, plus the server | You want images to stay on your own infrastructure |
| Cloudflare | Cloudflare Images, through OpenNext or a custom loader | 5,000 unique transformations a month free, then $0.50 per 1,000 | You already run on Cloudflare |
| Eurobase | Nowhere on the platform: images are served at their original size | Flat €10 or €20 a month + VAT for the workspace | You resize images during or before the build, or add a loader |
| Vercel | Vercel's image optimization, built in | Hobby includes 5,000 transformations a month, on-demand from $0.05 per 1,000 | You 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](/i/eu-region-vs-eu-company-cloud-act).

## 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](/i/nextjs-hosting-europe). To move an app, follow [Migrate from Vercel](/docs/guides/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

- [Next.js self-hosting guide](https://nextjs.org/docs/app/guides/self-hosting), [Image component reference](https://nextjs.org/docs/app/api-reference/components/image) and [images config](https://nextjs.org/docs/app/api-reference/config/next-config-js/images)
- [OpenNext Cloudflare image optimization](https://opennext.js.org/cloudflare/howtos/image) and [Cloudflare Images pricing](https://developers.cloudflare.com/images/pricing/)
- [Vercel image optimization limits and pricing](https://vercel.com/docs/image-optimization/limits-and-pricing)
- [Bunny Optimizer](https://bunny.net/optimizer/), [Bunny Optimizer pricing](https://bunny.net/pricing/optimizer/), [Bunny Optimizer pricing docs](https://docs.bunny.net/optimizer/pricing), [Bunny Dynamic Images API](https://docs.bunny.net/optimizer/dynamic-images) and [bunny.net terms](https://bunny.net/tos/)
- [imgproxy](https://imgproxy.net/) and [imgproxy on GitHub](https://github.com/imgproxy/imgproxy)
- [Sliplane Next.js hosting in Europe](https://sliplane.io/nextjs-hosting-europe), [Coolify Next.js docs](https://coolify.io/docs/applications/nextjs) and [Hetzner Cloud](https://www.hetzner.com/cloud/)
- [Next.js hosting on Eurobase](/hosting/nextjs), [Deploy a Next.js app](/docs/guides/nextjs), [Eurobase pricing](/pricing) and [Eurobase subprocessors](/legal/subprocessors)
