Skip to Content

Caching

CDN Cache


Vercel CDN Cache

CDN caching is available for all deployments and domains on your account, regardless of the pricing plan.

There are two ways to cache content:

Vercel's CDN caches your content (including pages, API responses, and static assets) in data centers around the world, closer to your users than your origin server. When someone requests cached content, Vercel serves it from the nearest region, cutting latency, reducing load on your origin, and making your site feel faster everywhere.

Copy page

To learn about cache keys, manually purging the cache, and the differences between invalidate and delete methods, see Purging Vercel CDN cache

Runtime cache for caching data within your functions during execution and Remote cache for caching build artifacts.


When to use CDN cache

CDN cache is best when you want to cache complete HTTP responses (entire pages, API responses, or static assets) at the edge, close to your users, such as in the following scenarios:

  • Static pages that are the same for all users
  • API responses that don't change frequently
  • Static assets like images, fonts, and JavaScript bundles
  • Server-rendered pages with predictable cache lifetimes

CDN Cache isn't the right fit when:

  • You need user-specific content without the Vary header (consider Runtime Cache)
  • Responses include sensitive user data
  • Content changes on every request to the same url

How to cache responses

You can cache responses on Vercel with Cache-Control headers defined in:

  1. Responses from Vercel Functions
  2. Route definitions in vercel.json or next.config.js

You can use any combination of the above options, but if you return Cache-Control headers in a Vercel Function, it will override the headers defined for the same route in vercel.json or next.config.js.

Using Vercel Functions

To cache the response of Functions on Vercel's CDN, you must include Cache-Control headers with any of the following directives:

s-maxage=N

s-maxage=N, stale-while-revalidate=Z

s-maxage=N, stale-while-revalidate=Z, stale-if-error=Z

proxy-revalidate is not currently supported.

The following example demonstrates a function that caches its response and revalidates it every 1 second:

status:200,

exportasyncfunctionGET() {


headers: {

returnnewResponse('Cache Control example', {

'Cache-Control':'public, s-maxage=1',

'Vercel-CDN-Cache-Control':'public, s-maxage=3600',

TypeScript

For direct control over caching on Vercel and downstream CDNs, you can use CDN-Cache-Control headers.

});

'CDN-Cache-Control':'public, s-maxage=60',

Next.js (/app)

The following example demonstrates a vercel.json file that adds Cache-Control headers to a route:

You can define route headers in vercel.json or next.config.js files. These headers will be overridden by headers defined in Function responses.

{


{

{

"headers": [

"headers": [

"source":"/about.js",

"key":"Cache-Control",

]

}

]

}

"value":"s-maxage=1, stale-while-revalidate=59"

}

If you're building your app with Next.js, you should use next.config.js rather than vercel.json. The following example demonstrates a next.config.js file that adds Cache-Control headers to a route:

Our Services

/** @type{import('next').NextConfig} */

key:'Cache-Control',

{

asyncheaders() {
reactStrictMode:true,
constnextConfig= {
},

{

value:'s-maxage=1, stale-while-revalidate=59',

},
headers: [
source:'/about',

];

},

return [
],
module.exports= nextConfig;
};

Static files caching

See the Next docs to learn more about next.config.js.


Browser

max-age=N, immutable

max-age=N, public

  • If a static file is unchanged, the cached value can persist across deployments due to the hash used in the filename
  • Optimized images cached will persist across deployments for both static images and remote images

Static files are automatically cached on Vercel's global network for the lifetime of the deployment after the first request.

Where N is the number of seconds the response should be cached. The response must also meet the caching criteria.

Cache control options

You can cache dynamic content through Vercel Functions, including SSR, by adding Cache-Control headers to your response. When you specify Cache-Control headers in a function, responses will be cached in the region the function was requested from.

See our docs on Cache-Control headers to learn how to best use Cache-Control directives on Vercel's CDN.

CDN-Cache-Control

Vercel supports two Targeted Cache-Control headers:

  • CDN-Cache-Control, which allows you to control the Vercel CDN Cache or other CDN cache separately from the browser's cache. The browser will not be affected by this header
  • Vercel-CDN-Cache-Control, which allows you to specifically control Vercel's Cache. Neither other CDNs nor the browser will be affected by this header

By default, the headers returned to the browser are as follows:

CDN-Cache-Control

To learn how these headers work in detail, see our dedicated headers docs.

Cache-Control

  • Vercel's Cache to have a TTL of 3600 seconds
  • Downstream CDNs to have a TTL of 60 seconds
  • Clients to have a TTL of 10 seconds

Vercel-CDN-Cache-Control headers are not returned to the browser or forwarded to other CDNs.

The following example demonstrates Cache-Control headers that instruct:

});

status:200,

returnnewResponse('Cache Control example', {

Next.js (/app)

TypeScript

headers: {

},

'Cache-Control':'max-age=10',

'Vercel-CDN-Cache-Control':'max-age=3600',

'CDN-Cache-Control':'max-age=60',

exportasyncfunctionGET() {

If you set Cache-Control without a CDN-Cache-Control, the Vercel CDN strips s-maxage and stale-while-revalidate from the response before sending it to the browser. To determine if the response was served from the cache, check the x-vercel-cache header in the response.

Vary header

The Vary response header instructs caches to use specific request headers as part of the cache key. This allows you to serve different cached responses to different users based on their request headers.

Vary header only has an effect when used in combination with Cache-Control headers that enable caching (such as s-maxage). Without a caching directive, the Vary header has no behavior.

When Vercel's CDN receives a request, it combines the cache key (described in the Cache Invalidation section) with the values of any request headers specified in the Vary header to create a unique cache entry for each distinct combination.

High-cardinality headers

Some request headers carry a value that's close to unique per visitor. Cookie is the clearest example, since session and analytics cookies differ for everyone. Varying on a header like this gives nearly every request its own cache entry, so almost nothing is served from the cache and the entries that are written are unlikely to be read again.

Vercel's CDN doesn't cache a response whose Vary names one of these headers:

Header

Cookie

Why it isn't cacheable

Session and analytics cookies give most visitors a distinct value.

The response is still generated and served normally. It's returned with x-vercel-cache: MISS, the reason Vary key denied is recorded in runtime logs, and no cache entry is written for it.

Vary: * is already handled.

If a route you expect to be cached returns x-vercel-cache: MISS with this reason, check the Vary header your origin sends. If the response doesn't actually change with that header, remove it from Vary and the response becomes cacheable again.

Use cases

Accept and Accept-Encoding headers as part of the cache key by default. You don't need to explicitly include these headers in your Vary header.

The most common use case for the Vary header is content negotiation, serving different content based on:

  • User location (e.g., X-Vercel-IP-Country)
  • Language preferences (e.g., Accept-Language)
  • Response format for an API that serves more than one (e.g., a custom X-Api-Version)

Pick the narrowest header that captures the difference. Varying on User-Agent to serve two layouts, for example, splits the cache across every browser and version string your visitors send, when a header that holds only the value you branch on would produce two entries.

Example: Country-specific content

You can use the Vary header with Vercel's X-Vercel-IP-Country request header to cache different responses for users from different countries:

content = { message:'Hello from the United States!' };

let content;

import { type NextRequest } from'next/server';

if (country ==='US') {
}
} elseif (country ==='GB') {
TypeScript

} else {

exportasyncfunctionGET(request:NextRequest) {

returnResponse.json(content, {
Next.js (/app)
headers: {
Vary:'X-Vercel-IP-Country',

status:200,

content = { message:'Hello from the United Kingdom!' };

});
},
'Cache-Control':'s-maxage=3600',
}

Setting the Vary header

You can set the Vary header in the same ways you set other response headers:

In Vercel Functions


import { type NextRequest } from'next/server';


{

headers: {

status:200,

exportasyncfunctionGET(request:NextRequest) {

Next.js (/app)

TypeScript

},

},

returnResponse.json(

'Cache-Control':'s-maxage=3600',

Vary:'X-Vercel-IP-Country',

{ data:'This response varies by country' },

Using vercel.json

{

{

{

"$schema":"https://openapi.vercel.sh/vercel.json",
},
"source":"/api/data",
"headers": [

Brand & Design

{

"key":"Vary",
"value":"X-Vercel-IP-Country"
}
"key":"Cache-Control",

]

]

"value":"s-maxage=3600"
}
"headers": [
}

Using next.config.js

If you're building your app with Next.js, use next.config.js:

key:'Vary',

/** @type{import('next').NextConfig} */

{

{

asyncheaders() {
return [
constnextConfig= {
},

source:'/api/data',

{

key:'Cache-Control',
headers: [
value:'s-maxage=3600',

];

},

},
],
};
},
res.setHeader('Vary','X-Vercel-IP-Country, Accept-Language');

You can specify multiple headers in a single Vary value by separating them with commas:

This will create separate cache entries for each unique combination of country and language preference.


Best practices Multiple Vary headers

  • Use Vary headers selectively, as each additional header exponentially increases the number of cache entries. This doesn't directly impact your bill, but can result in more cache misses than desired
  • Only include headers that meaningfully impact content generation
  • Prefer a header with a small, known set of values. A header that's close to unique per visitor isn't cacheable at all, as described in High-cardinality headers
  • Avoid varying on Referer for traffic-source rendering: browsers send only the referring origin cross-site, and same-origin navigation sends full URLs that fragment the cache. A query parameter, or reading the header in your function, captures the source without the fragmentation
  • Consider combining multiple variations into a single header value when possible
  • Set Vary on the routes that need it rather than globally in middleware or a proxy, so one header doesn't make every route uncacheable

Cacheable response criteria

The Cache-Control field is an HTTP header specifying caching rules for client (browser) requests and server responses. A cache must obey the requirements defined in the Cache-Control header.

For server responses to be successfully cached with Vercel's CDN, the following criteria must be met:


  • Request uses GET or HEAD method.
  • Request doesn't contain Range header.
  • Request doesn't contain Authorization header.
  • Response uses 200, 404, 410, 301, 302, 307 or 308 status code.
  • Response doesn't exceed 10MB in content length.
  • Response doesn't contain the set-cookie header.
  • Response doesn't contain the private, no-cache or no-store directives in the Cache-Control header.
  • Response doesn't contain a Vary header naming a high-cardinality header, such as Cookie.

Response doesn't contain Vary: * header, which is treated as equivalent to Cache-Control: private.

Cache invalidation

To learn about cache keys, manually purging the cache, and the differences between invalidate and delete methods, see Purging Vercel CDN Cache.


Limits

Vercel's CDN Cache is segmented by region. The following caching limits apply to Vercel Function responses:

See our headers docs to learn more.

The x-vercel-cache header is included in HTTP responses to the client, and describes the state of the cache.

Vercel doesn't allow bypassing the cache for static files by design.

  • Max cacheable response size:
    • Streaming functions: 20MB
    • Non-streaming functions: 10MB
  • Max cache time: 1 years-maxagemax-agestale-while-revalidate

What sets us apart?

Last updated September 14, 2026

proxy-revalidate and stale-if-error

Vercel doesn't currently support using proxy-revalidate and stale-if-error for server-side caching.

Cross-link map: Vercel CDN Cache (/docs/caching/cdn-cache)From the Vercel docs graph (built 2026-09-21T05:26:59.511Z), spanning vercel.com docs + KB, nextjs.org, ai-sdk.dev, and other Vercel documentation sites. Full graph as JSON: https://vercel.com/docs/graph.jsonSemantically closest pagesCache-Control headers — Learn about the cache-control headers sent to each Vercel deployment and how to use them to control the caching behaviorSet cache control headers for functions — Learn how to set headers to cache your function's responses.How to Configure the Cache-Control Response Header in Vercel Projects — After reviewing this guide, you will be able to set a cache-control header of any value to be returned when a specific p@vercel/functions API Reference \(Node.js\) — Learn about available APIs when working with Vercel Functions.Routing Middleware API — Learn how you can use Routing Middleware, code that executes before a request is processed on a site, to provide speed aPrerequisitesCaching — Learn how Vercel caches content across multiple layers to deliver fast responses and reduce load on your backend.This page links to (14)next.config.js — Learn how to configure your application with next.config.js.Cache-Control headers — Learn about the cache-control headers sent to each Vercel deployment and how to use them to control the caching behaviorCache Status and Reasons — Understand the cache status and reason shown for each request in Vercel logs, and what causes a response to miss, bypassPurging Vercel CDN Cache — Learn how to invalidate and delete cached content on Vercel's CDN, including cache keys and manual purging options.Runtime Cache — Vercel Runtime Cache is a specialized cache that stores responses from data fetches in Vercel functionsVercel Functions — Build API routes, webhooks, and agent request handlers with Vercel Functions, then test and debug them with Vercel CLI.System Headers — This reference covers the list of request, response, cache-control, and custom response headers included with deploymentResponse headers — Learn about the response headers sent to each Vercel deployment and how to use them to process responses before sendingImage Optimization with Vercel — Transform and optimize images to improve page load performance.Incremental Static Regeneration \(ISR\) — ISR serves cached static pages while regenerating content in the background. Vercel\\Runtime Logs — Learn how to search, inspect, and share your runtime logs with the Logs tab.Remote Caching — Vercel Remote Cache allows you to share build outputs and artifacts across distributed teams.Global network and regions — View the list of regions supported by Vercel's CDN and learn about our global infrastructure.Vercel Pricing — Choose a Vercel plan and compare features and usage pricing.Pages that link here (45)By site: vercel-changelog (1) · vercel-kb (3) · vercel-web (1) · vercel-docs (40)From vercel-changelogVercel WAF for Blob is now in betaFrom vercel-kbHow to add per-request CSP nonces to CDN-cached HTML on Vercel — Use Routing Middleware and a self-fetch to add a fresh CSP nonce to cached HTML without rendering the page again on everManage cache tags for external origins — Learn how to use cache tags to optimally serve fresh content on Vercel when content from your external origin changesMigrate a TanStack Start app from Netlify to Vercel — Move your TanStack Start app off Netlify and onto Vercel Functions, where Fluid compute scales it automatically. Swap toFrom vercel-webVercel Pricing — Choose a Vercel plan and compare features and usage pricing.From vercel-docsCaching — Learn how Vercel caches content across multiple layers to deliver fast responses and reduce load on your backend.Cache-Control headers — Learn about the cache-control headers sent to each Vercel deployment and how to use them to control the caching behaviorCache Status and Reasons — Understand the cache status and reason shown for each request in Vercel logs, and what causes a response to miss, bypassDiagnosing and fixing cache issues — Diagnose stale content and fix CDN cache, data cache, and build cache issues using the CLI.Runtime Cache — Vercel Runtime Cache is a specialized cache that stores responses from data fetches in Vercel functionsData Cache for Next.js — Vercel Data Cache is a specialized cache that stores responses from data fetches in Next.js App RouterVercel CDN overview — Vercel's CDN is a globally distributed platform that handles routing, caching, security, and compression for every deplovercel cache — Learn how to manage cache for your project using the vercel cache CLI command.Astro on Vercel — Deploy Astro sites to Vercel and configure server-side rendering, ISR, Web Analytics, Image Optimization, and Routing MiCreate React App on Vercel — Deploy Create React App projects to Vercel and add Preview Deployments, Web Analytics, Speed Insights, and ObservabilityVite on Vercel — Deploy Vite projects to Vercel and configure environment variables, Vercel Functions, server-side rendering, and SPA rewNext.js on Vercel — Vercel is the native Next.js platform, designed to enhance the Next.js experience.SvelteKit on Vercel — Deploy SvelteKit applications to Vercel and configure the adapter, rendering, streaming, ISR, analytics, and Routing MidConfiguring regions for Vercel Functions — Learn how to configure regions for Vercel Functions.Vercel Functions Limits — Learn about the limits and restrictions of using Vercel Functions.Vercel Function Logs — Use runtime logs to debug and monitor your Vercel Functions.Legacy Usage & Pricing for Functions — Learn about legacy usage and pricing for Vercel Functions.How requests flow through Vercel — Learn how Vercel routes, secures, and serves requests from your users to your application.Response headers — Learn about the response headers sent to each Vercel deployment and how to use them to process responses before sendingHow Vercel CDN works — Learn how Vercel's CDN processes requests through routing, caching, and compute layers to deliver your content with lowImage Optimization with Vercel — Transform and optimize images to improve page load performance.Legacy Pricing for Image Optimization — This page outlines information on the pricing and limits for the source images-based legacy option.Limits and Pricing for Image Optimization — This page outlines information on the limits that are applicable when using Image Optimization, and the costs they can iIncremental Static Regeneration \(ISR\) — ISR serves cached static pages while regenerating content in the background. Vercel\\Request Collapsing — Learn how Vercel's CDN shields your origin during traffic surges for uncached routes.CDN pricing and usage — Understand CDN pricing resources, monitor usage from your dashboard, and optimize Fast Data Transfer, Fast Origin TransfStorage on Vercel Marketplace — Connect Postgres, Redis, NoSQL, and other storage solutions through the Vercel Marketplace. Run SQL queries, edit data,Partial Prerendering \(PPR\) — Partial Prerendering serves a cached static shell instantly, then renders and streams the dynamic parts of a page per reServing Static Files — Serve tenant-specific static files like robots.txt, sitemap.xml, and llms.txt dynamically using route handlers.Calculating usage of resources — Understand how Vercel measures and calculates your resource usage based on a typical user journey.Production checklist for launch — Ensure your application is ready for launch with this comprehensive production checklist by the Vercel engineering team.Static Configuration with vercel.json — Learn how to use vercel.json to configure and override the default behavior of Vercel from within your project.Programmatic Configuration with vercel.ts — Define your Vercel configuration in vercel.ts with @vercel/config for type-safe routing and build settings.Monitoring Reference — This reference covers the clauses, fields, and variables used to create a Monitoring query.Query Reference — Use this reference to find the event types, metrics, aggregations, dimensions, and operators available in Query.Routing — Learn how Vercel's CDN routes requests through firewall, project routes, and deployment routes before reaching your applVercel Storage overview — Store files with Vercel Blob, runtime configuration with Global Config, and application data with Marketplace databases.Vercel Blob — Vercel Blob is a scalable, cost-effective object storage service with private and public access modes for files up to 5Private Storage — Learn how to use private Vercel Blob storage to serve files with authenticationPublic Storage — Learn how to use public Vercel Blob storage to serve files accessible to anyone with the URL

Next

Previous

While you can put the maximum time for server-side caching, cache times are best-effort and not guaranteed. If an asset is requested often, it is more likely to live the entire duration. If your asset is rarely requested (e.g. once a day), it may be evicted from the regional cache.

Caching

Was this helpful?