Vercel's CDN Cache caches your content at the edge in order to serve data to your users as fast as possible. Vercel's caching is available for all deployments and domains on your account, regardless of the pricing plan.
Vercel uses the CDN to cache your content globally and serve data to your users as quickly as possible. There are two ways to cache content:
Static file caching is automatic for all deployments, requiring no manual configuration
To cache dynamic content, including SSR content, you can use Cache-Controlheaders
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.
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:
You can cache dynamic content through Vercel Functions, including SSR, by adding Cache-Controlheaders to your response. When you specify Cache-Control headers in a function, responses will be cached in the region the function was requested from.
CDN-Cache-Control, which allows you to control the Vercel 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:
Cache-Control
CDN-Cache-Control
Vercel-CDN-Cache-Control headers are not returned to the browser or forwarded to other CDNs.
exportasyncfunctionGET() {returnnewResponse('Cache Control example', { status:200, headers: {'Cache-Control':'max-age=10','CDN-Cache-Control':'max-age=60','Vercel-CDN-Cache-Control':'max-age=3600', }, });}
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.
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.
The 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.
Vercel's CDN already includes the Accept and Accept-Encoding headers as
part of the cache key by default. You do not 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)
Device type (e.g., User-Agent)
Language preferences (e.g., Accept-Language)
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:
app/api/country-specific/route.ts
TypeScript
import { type NextRequest } from'next/server';exportasyncfunctionGET(request:NextRequest) {constcountry=request.headers.get('x-vercel-ip-country') ||'unknown';// Serve different content based on countrylet content;if (country ==='US') { content = { message:'Hello from the United States!' }; } elseif (country ==='GB') { content = { message:'Hello from the United Kingdom!' }; } else { content = { message:`Hello from ${country}!` }; }returnResponse.json(content, { status:200, headers: {'Cache-Control':'s-maxage=3600', Vary:'X-Vercel-IP-Country', }, });}
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
Consider combining multiple variations into a single header value when possible
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 does not contain Range header.
Request does not contain Authorization header.
Response uses 200, 404, 301, 302, 307 or 308 status code.
Response does not exceed 10MB in content length.
Response does not contain the set-cookie header.
Response does not contain the private, no-cache or no-store directives in the Cache-Control header.
Response does not contain Vary: * header, which is treated as equivalent to Cache-Control: private.
Vercel does not allow bypassing the cache for static files by design.
Vercel's Edge Cache is segmented by region. The following caching limits apply to Vercel Function responses:
Max cacheable response size:
Streaming functions: 20MB
Non-streaming functions: 10MB
Max cache time: 1 year
s-maxage
max-age
stale-while-revalidate
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.