Headers Included with Deployments
This reference covers the list of request, response, cache-control, and custom response headers included with deployments with Vercel.Headers are small pieces of information that are sent between the client (usually a web browser) and the server. They contain metadata about the request and response, such as the content type, cache-control directives, and authentication tokens. HTTP headers can be found in both the HTTP Request and HTTP Response.
By using headers effectively, you can optimize the performance and security of your application on Vercel's edge network. Here are some tips for using headers on Vercel:
- Use caching headers: Caching headers instruct the client and server to cache resources like images, CSS files, and JavaScript files, so they don't need to be reloaded every time a user visits your site. By using caching headers, you can significantly reduce the time it takes for your site to load.
- Use compression headers: Use the
Accept-Encoding
header to tell the client and server to compress data before it's sent over the network. By using compression, you can reduce the amount of data that needs to be sent, resulting in faster load times. - Use custom headers: You can also use custom headers in your
vercel.json
file to add metadata specific to your application. For example, you could add a header that indicates the user's preferred language or the version of your application. See Project Configuration docs for more information.
The following headers are sent to each Vercel deployment and can be used to process the request before sending back a response. These headers can be read from the Request object in your Serverless Function.
This header represents the domain name as it was accessed by the client. If the deployment has been assigned to a preview URL or production domain and the client visits the domain URL, it contains the custom domain instead of the underlying deployment URL.
This header contains a list of Edge regions your request hit, as well as the region the function was executed in (for both Edge and Serverless).
It also allows Vercel to automatically prevent infinite loops.
This header is identical to the host
header.
This header represents the protocol of the forwarded server, typically https
in production and http
in development.
The public IP address of the client that made the request.
If you are trying to use Vercel behind a proxy, we currently overwrite the X-Forwarded-For
header and do not forward external IPs. This restriction is in place to prevent IP spoofing.
Trusted Proxy is available on Enterprise plans
Enterprise customers can purchase and enable a trusted proxy to allow your custom X-Forwarded-For
IP. Contact us for more information.
This header is identical to the x-forwarded-for
header. However, x-forwarded-for
could be overwritten if you're using a proxy on top of Vercel.
This header is identical to the x-forwarded-for
header.
This header represents the unique deployment, not the preview URL or production domain. For example, *.vercel.app
.
A two-character ISO 3166-1 code representing the continent associated with the location of the requester's public IP address. Codes used to identify continents are as follows:
AF
for AfricaAN
for AntarcticaAS
for AsiaEU
for EuropeNA
for North AmericaOC
for OceaniaSA
for South America
A two-character ISO 3166-1 country code for the country associated with the location of the requester's public IP address.
A string of up to three characters containing the region-portion of the ISO 3166-2 code for the first level region associated with the requester's public IP address. Some countries have two levels of subdivisions, in which case this is the least specific one. For example, in the United Kingdom this will be a country like "England", not a county like "Devon".
The city name for the location of the requester's public IP address. Non-ASCII characters are encoded according to RFC3986.
The latitude for the location of the requester's public IP address. For example, 37.7749
.
The longitude for the location of the requester's public IP address. For example, -122.4194
.
The name of the time zone for the location of the requester’s public IP address in ICANN Time Zone Database name format such as America/Chicago
.
The signature of the request. This header is used to verify that the request was sent by Vercel, and contains a hash signature you can use to validate the request body.
The following headers are included in Vercel deployment responses and indicate certain factors of the environment. These headers can be viewed from the Browser's Dev Tools or using an HTTP client such as curl -I <DEPLOYMENT_URL>
.
Used to specify directives for caching mechanisms in both the Network layer cache and the browser cache. See the Cache Control Headers section for more detail.
If you use this header to instruct the Edge Network to cache data, such as with the s-maxage
directive, Vercel returns the following cache-control
header to the client:
-cache-control: public, max-age=0, must-revalidate
An integer that indicates the number of bytes in the response.
The media type that describes the nature and format of the response.
A timestamp indicating when the response was generated.
Shows where the request came from. This header can be overridden by other proxies (e.g., Cloudflare).
A header often abbreviated as HSTS that tells browsers that the resource should only be requested over HTTPS. The default value is strict-transport-security: max-age=63072000
(2 years)
Present only on:
- Preview Deployments
- Outdated Production Deployments. When you promote a new deployment to production, the
x-robots-tag
header will be sent to requests for outdated production deployments
We add this header automatically with a value of noindex
to prevent search engines from crawling your Preview Deployments and outdated Production Deployments, which could cause them to penalize your site for duplicate content.
You can prevent this header from being added to your Preview Deployment by:
- Assigning a production domain to it
- Disabling it manually using vercel.json
This header's value indicates whether the response was served from Vercel's edge cache.
The following values are possible when the content being served is static or uses a Cache-Control header:
The response was not found in the edge cache and was fetched from the origin server.
The response was served from the edge cache.
The response was served from the edge cache. A background request to the origin server was made to update the content. A background request to the origin was made to get a fresh version. (see Stale-While-Revalidate for more information)
The response was served from static storage. An example of prerender is in Next.js
, when setting fallback:true
in getStaticPaths
. However, fallback:blocking
will not return prerender.
The response was served from the origin server and the cache was refreshed due to an authorization from the user in the incoming request.
This header contains a list of Edge regions your request hit, as well as the region the function was executed in (for both Edge and Serverless).
It also allows Vercel to automatically prevent infinite loops.
You can control how Vercel's Edge Network caches your Function responses by setting a Cache-Control headers header.
The default value is cache-control: public, max-age=0, must-revalidate
which instructs both the Edge Network and the browser not to cache.
We recommend that you set your cache tomax-age=0, s-maxage=86400
, adjusting 86400 to the number of seconds you want the response cached. This configuration tells browsers not to cache, allowing Vercel's Edge Network to cache responses and invalidate them when deployments update.
This directive sets the number of seconds a response is considered "fresh" by the Edge Network. After this period ends, Vercel's Edge Network will serve the "stale" response from the edge until the response is asynchronously revalidated with a "fresh" response to your Serverless Function.
s-maxage
is consumed by Vercel's proxy and not included as part the final HTTP response to the client.
The following example instructs the Edge Network to cache the response for 60 seconds. A response can be cached a minimum of 1
second and maximum of 31536000
seconds (1 year).
Cache-Control: s-maxage=60
This cache-control
directive allows you to serve content from the Edge cache while simultaneously updating the cache in the background with the response from your function. It is useful when:
- Your content changes frequently, but regeneration is slow, such as content that relies on an expensive database query or upstream API request
- Your content changes infrequently but you want to have the flexibility to update it without waiting for the cache to expire
stale-while-revalidate
is consumed by Vercel's proxy and not included as part the final HTTP response to the client. This allows you to deliver the latest content to your visitors right after creating a new deployment (as opposed to waiting for browser cache to expire). It also prevents content-flash.
The following example instructs the Edge Network to:
- Serve content from the Edge cache for 1 second
- Return a stale request (if requested after 1 second)
- Update the cache in the background asynchronously (if requested after 1 second)
Cache-Control: s-maxage=1, stale-while-revalidate=59
The first request is served synchronously. Subsequent requests are served from the cache and revalidated asynchronously if the cache is "stale".
If you need to do a synchronous revalidation you can set the pragma: no-cache
header along with the cache-control
header. This can be used to understand how long the background revalidation took. It sets the x-vercel-cache
header to REVALIDATED
.
Many browser developer tools set pragma: no-cache
by
default, which reveals the true load time of the page with the synchronous
update to the cache.
This directive is currently not supported. stale-if-error
is consumed by Vercel's proxy, and will not be included in the HTTP response sent to the client.
This directive is currently not supported.
Using the private
directive specifies that the response can only be cached by the client and not by Vercel's Edge Network. Use this directive when you want to cache content on the user's browser, but prevent caching on Vercel's Edge Network.
When Vercel's Edge Network CDN receives a request with Pragma: no-cache
(such as when the browser devtools are open), it will revalidate any stale resource synchronously, instead of in the background.
Sometimes the directives you set in a Cache-Control
header can be interpreted differently by the different CDNs and proxies your content passes through between the origin server and a visitor's browser. To explicitly control caching you can use targeted cache control headers.
The CDN-Cache-Control
and Vercel-CDN-Cache-Control
headers are response headers that can be used to specify caching behavior on the Edge Network and/or CDNs.
You can use the same directives as Cache-Control
, but CDN-Cache-Control
is only used by the Edge Network and CDNs.
Origins can set the following headers:
Vercel-CDN-Cache-Control
CDN-Cache-Control
Cache-Control
When multiple of the above headers are set, Vercel's Edge Network will use the following priority to determine the caching behavior:
Vercel-CDN-Cache-Control
is exclusive to Vercel and has top priority, whether it's defined in a Vercel Function response or a vercel.json
file. It controls caching behavior only within Vercel's Edge Cache. It is removed from the response and not sent to the client or any CDNs.
CDN-Cache-Control
is second in priority after Vercel-CDN-Cache-Control
, and always overrides Cache-Control
headers, whether defined in a Vercel Function response or a vercel.json
file.
By default, CDN-Cache-Control
configures Vercel's Edge Cache and is used by other CDNs, allowing you to configure intermediary caches. If Vercel-CDN-Cache-Control
is also set, CDN-Cache-Control
only influences other CDN caches.
Cache-Control
is a web standard header and last in priority. If neither CDN-Cache-Control
nor Vercel-CDN-Cache-Control
are set, this header will be used by Vercel's Edge Cache before being forwarded to the client.
You can still set Cache-Control
while using the other two, and it will be forwarded to the client as is.
If only Cache-Control
is used, Vercel strips the
s-maxage
directive from the header before it's sent to the client.
The following tables demonstrate how Vercel's Edge Cache behaves in different scenarios:
Cache-Control
headers returned from Vercel Functions take priority over Cache-Control
headers from next.config.js
or vercel.json
files.
Parameter | Value |
---|---|
Vercel Function response headers | Cache-Control: s-maxage=60 |
vercel.json or next.config.js headers | Cache-Control: s-maxage: 120 |
Cache behavior | 60s TTL |
Headers sent to the client | Cache-Control: public, max-age: 0 |
CDN-Cache-Control
has priority over Cache-Control
, even if defined in vercel.json
or next.config.js
.
Parameter | Value |
---|---|
Vercel Function response headers | Cache-Control: s-maxage=60 |
vercel.json or next.config.js headers | CDN-Cache-Control: max-age=120 |
Cache behavior | 120s TTL |
Headers sent to the client | Cache-Control: s-maxage=60 CDN-Cache-Control: max-age=120 |
Vercel-CDN-Cache-Control
has priority over both CDN-Cache-Control
and Cache-Control
. It only applies to Vercel, so it is not returned with the other headers, which will control cache behavior on the browser and other CDNs.
Parameter | Value |
---|---|
Vercel Function response headers | CDN-Cache-Control: max-age=120 |
vercel.json or next.config.js headers | Cache-Control: s-maxage=60 Vercel-CDN-Cache-Control: max-age=300 |
Cache behavior | 300s TTL |
Headers sent to the client | Cache-Control: s-maxage=60 CDN-Cache-Control: max-age=120 |
- If you want to control caching similarly on Vercel, CDNs, and the client, use
Cache-Control
- If you want to control caching on Vercel and also on other CDNs, use
CDN-Cache-Control
- If you want to control caching only on Vercel, use
Vercel-CDN-Cache-Control
- If you want to specify different caching behaviors for Vercel, other CDNs, and the client, you can set all three headers
The following example demonstrates Cache-Control
headers that instruct:
- Vercel's Edge 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
export async function GET() {
return new Response('Cache Control example', {
status: 200,
headers: {
'Cache-Control': 'max-age=10',
'CDN-Cache-Control': 'max-age=60',
'Vercel-CDN-Cache-Control': 'max-age=3600',
},
});
}
Using configuration, you can assign custom headers to each response.
Custom headers can be configured with the headers
property in next.config.js
for Next.js projects, or it can be configured in vercel.json
for all other projects.
Alternatively, a Serverless Function can assign headers to the Response object.
Response headers x-matched-path
,
server
, and content-length
are reserved and cannot be modified.
Was this helpful?