Vercel supports dynamically transforming unoptimized images to reduce the file size while maintaining high quality. These optimized images are cached on the Vercel CDN, meaning they're available close to users whenever they're requested.
The flow of image optimization on Vercel involves several steps, starting from the image request to serving the optimized image.
The optimization process starts with your component choice in your codebase:
If you use a standard HTML img element, the browser will be instructed to bypass optimization and serve the image directly from its source.
If you use a framework's Image component (like next/image) it will use Vercel's image optimization pipeline, allowing your images to be automatically optimized and cached.
When Next.js receives an image request, it checks the unoptimized prop on the Image component or the configuration in the next.config.ts file to determine if optimization is disabled.
If you set the unoptimized prop on the Image component to true, Next.js bypasses optimization and serves the image directly from its source.
If you don't set the unoptimized prop or set it to false, Next.js checks the next.config.ts file to see if optimization is disabled. This configuration applies to all images and overrides the individual component prop.
If neither the unoptimized prop is set nor optimization is disabled in the next.config.ts file, Next.js continues with the optimization process.
If optimization is enabled, Vercel validates the loader configuration (whether using the default or a custom loader) and verifies that the image source URL matches the allowed patterns defined in your configuration (remotePatterns or localPatterns).
Vercel then checks the status of the cache to see if an image has been previously cached:
HIT: The image is fetched and served from the cache, either in region or from the shared global cache.
Content where images play a central role (e.g. photography portfolios)
In some cases, Image Optimization may not be necessary or beneficial, such as:
Small icons or thumbnails (under 10 KB)
Animated image formats such as GIFs
Vector image formats such as SVG
Frequently changing images where caching could lead to outdated content
If your images meet any of the above criteria where Image Optimization is not beneficial, we recommend using the unoptimized prop on the Next.js Image component. For guidance on SvelteKit, Astro, or Nuxt, see their documentation.
It's important that you are only optimizing images that need to be optimized otherwise you could end up using your image usage quota unnecessarily. For example, if you have a small icon or thumbnail that is under 10 KB, you should not use Image Optimization as these images are already very small and optimizing them further would not provide any benefits.
An important aspect of using the Image component is properly setting up remote/local patterns in your next.config.ts file. This configuration determines which images are allowed to be optimized.
You can set up patterns for both local images (stored as static assets in your public folder) and remote images (stored externally). In both cases you specify the pathname the images are located at.
In the case of external images, you should consider adding your account id to the pathname if you don't own the hostname. For example pathname: '/account123/v12h2bv/**'. This helps protect your source images from potential abuse.
Redeploying your app doesn't invalidate the image cache
To invalidate, add a query string to the src property (e.g., ?v=2), then redeploy.
Alternatively, you can configure the cache to expire more frequently.
Remote image cache expiration:
TTL is determined by the Cache-Controlmax-age header from the upstream image or minimumCacheTTL config (default: 3600 seconds), whichever is larger.
If your image content changes frequently, it's best to keep this TTL short.
Once an image is cached, it remains so even if you update the source image. For remote images, users accessing a URL with a previously cached image will see the old version until the cache expires or the image is invalidated. Each time an image is requested, it counts towards your Fast Data Transfer and Edge Request usage for your billing cycle.
See Pricing for more information, and read more about caching behavior in the Next.js documentation.
When you use the Image component in common frameworks and deploy your project on Vercel, Image Optimization automatically adjusts your images for different device screen sizes. The src prop you provided in your code is dynamically replaced with an optimized image URL. For example:
The Image Optimization API has the following query parameters:
url: The URL of the source image to be transformed. This can be a local image (relative url) or remote image (absolute url).
w: The width of the transformed image in pixels. No height is needed since the source image aspect ratio is preserved.
q: The quality of the transformed image, between 1 (lowest quality) and 100 (highest quality).
The allowed values of those query parameters are determined by the framework you are using, such as next.config.js for Next.js.
If you are not using a framework that comes with an Image component or you are building your own framework, refer to the Build Output API to see how the build output from a framework can configure the Image Optimization API.
If you are building a custom web framework, you can also use the Build Output API to implement Image Optimization. To learn how to do this, see the Build your own web framework blog post.