The Cache-Control
HTTP header holds directives (instructions) for caching in both requests and responses. A given directive in a request does not mean the same directive should be in the response.
Header type | General header |
---|---|
Forbidden header name | no |
CORS-safelisted response header | yes |
Syntax
Caching directives have the following rules to be valid:
- Case-insensitive, but lowercase is recommended.
- Multiple directives are comma-separated.
- Some directives have an optional argument, which can be either a token or a quoted-string. (See spec for definitions)
Cache request directives
Standard Cache-Control
directives that can be used by the client in an HTTP request.
Cache-Control: max-age=<seconds> Cache-Control: max-stale[=<seconds>] Cache-Control: min-fresh=<seconds> Cache-Control: no-cache Cache-Control: no-store Cache-Control: no-transform Cache-Control: only-if-cached
Cache response directives
Standard Cache-Control
directives that can be used by the server in an HTTP response.
Cache-Control: must-revalidate Cache-Control: no-cache Cache-Control: no-store Cache-Control: no-transform Cache-Control: public Cache-Control: private Cache-Control: proxy-revalidate Cache-Control: max-age=<seconds> Cache-Control: s-maxage=<seconds>
Extension Cache-Control directives
Extension Cache-Control
directives are not part of the core HTTP caching standards document. Check the compatibility table for their support; user-agents that don't recognize them should ignore them.
Cache-Control: immutable Cache-Control: stale-while-revalidate=<seconds> Cache-Control: stale-if-error=<seconds>
Directives
Cacheability
A response is normally cached by the browser if:
- it has a status code of
301
,302
,307
,308
, or410
and Cache-Control
does not haveno-store
, or if proxy, does not haveprivate
andAuthorization
is unset- either
public
- The response may be stored by any cache, even if the response is normally non-cacheable.
private
- The response may be stored only by a browser's cache, even if the response is normally non-cacheable. If you mean to not store the response in any cache, use
no-store
instead. This directive is not effective in preventing caches from storing your response. no-cache
- The response may be stored by any cache, even if the response is normally non-cacheable. However, the stored response MUST always go through validation with the origin server first before using it, therefore, you cannot use
no-cache
in-conjunction withimmutable
. If you mean to not store the response in any cache, useno-store
instead. This directive is not effective in preventing caches from storing your response. no-store
- The response may not be stored in any cache. Although other directives may be set, this alone is the only directive you need in preventing cached responses on modern browsers.
max-age=0
is already implied. Settingmust-revalidate
does not make sense because in order to go through revalidation you need the response to be stored in a cache, whichno-store
prevents.
Expiration
max-age=<seconds>
- The maximum amount of time a resource is considered fresh. Unlike
Expires
, this directive is relative to the time of the request. s-maxage=<seconds>
- Overrides
max-age
or theExpires
header, but only for shared caches (e.g., proxies). Ignored by private caches. max-stale[=<seconds>]
- Indicates the client will accept a stale response. An optional value in seconds indicates the upper limit of staleness the client will accept.
min-fresh=<seconds>
- Indicates the client wants a response that will still be fresh for at least the specified number of seconds.
stale-while-revalidate=<seconds>
- Indicates the client will accept a stale response, while asynchronously checking in the background for a fresh one. The seconds value indicates how long the client will accept a stale response. See "Keeping things fresh with
stale-while-revalidate
" for more information. stale-if-error=<seconds>
- Indicates the client will accept a stale response if the check for a fresh one fails. The seconds value indicates how long the client will accept the stale response after the initial expiration.
Revalidation and reloading
must-revalidate
- Indicates that once a resource becomes stale, caches must not use their stale copy without successful validation on the origin server.
proxy-revalidate
- Like
must-revalidate
, but only for shared caches (e.g., proxies). Ignored by private caches. immutable
- Indicates that the response body will not change over time. The resource, if unexpired, is unchanged on the server and therefore the client should not send a conditional revalidation for it (e.g.
If-None-Match
orIf-Modified-Since
) to check for updates, even when the user explicitly refreshes the page. Clients that aren't aware of this extension must ignore them as per the HTTP specification. In Firefox,immutable
is only honored onhttps://
transactions. For more information, see also this blog post.
Other
no-transform
- An intermediate cache or proxy cannot edit the response body,
Content-Encoding
,Content-Range
, orContent-Type
. It therefore forbids a proxy or browser feature, such as Google’s Web Light, from converting images to minimize data for a cache store or slow connection. only-if-cached
- Set by the client to indicate "do not use the network" for the response. The cache should either respond using a stored response, or respond with a
504
status code. Conditional headers such asIf-None-Match
should not be set. There is no effect ifonly-if-cached
is set by a server as part of a response.
Examples
Preventing caching
To disable caching of a resource, you can send the following response header:
- Good:
-
Cache-Control: no-store
- Bad:
-
Cache-Control: private,no-cache,no-store,max-age=0,must-revalidate,pre-check=0,post-check=0
Caching static assets
For the files in the application that will not change, you can usually add aggressive caching by sending the response header below. This includes static files that are served by the application such as images, CSS files and JavaScript files, for example. In addition, see also the Expires
header.
Cache-Control: public, max-age=604800, immutable
Requiring revalidation
Specifying no-cache
or max-age=0
indicates that clients can cache a resource and must revalidate each time before using it. This means HTTP request occurs each time, but it can skip downloading HTTP body if the content is valid.
Cache-Control: no-cache Cache-Control: no-cache, max-age=0
Specifications
Specification | Status | Comment |
---|---|---|
RFC 8246: HTTP Immutable Responses | IETF RFC | |
RFC 7234: Hypertext Transfer Protocol (HTTP/1.1): Caching | IETF RFC | |
RFC 5861: HTTP Cache-Control Extensions for Stale Content | IETF RFC | Initial definition |
Browser compatibility
Desktop | Mobile | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Cache-Control | Chrome Full support Yes | Edge Full support 12 | Firefox Full support Yes | IE Full support Yes | Opera Full support Yes | Safari Full support Yes | WebView Android Full support Yes | Chrome Android Full support Yes | Firefox Android Full support Yes | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support Yes |
immutable | Chrome
No support
No
| Edge No support 15 — 79 | Firefox Full support 49 | IE No support No | Opera No support No | Safari Full support 11 | WebView Android No support No | Chrome Android No support No | Firefox Android No support No | Opera Android No support No | Safari iOS Full support 11 | Samsung Internet Android No support No |
stale-if-error | Chrome
No support
No
| Edge
No support
No
| Firefox
No support
No
| IE No support No | Opera No support No | Safari No support No | WebView Android No support No | Chrome Android No support No | Firefox Android No support No | Opera Android No support No | Safari iOS No support No | Samsung Internet Android No support No |
stale-while-revalidate | Chrome Full support 75 | Edge Full support 79 | Firefox Full support 68 | IE No support No | Opera No support No | Safari No support No | WebView Android Full support 75 | Chrome Android Full support 75 | Firefox Android Full support 68 | Opera Android No support No | Safari iOS No support No | Samsung Internet Android No support No |
Legend
- Full support
- Full support
- No support
- No support
- Experimental. Expect behavior to change in the future.
- Experimental. Expect behavior to change in the future.
- Non-standard. Expect poor cross-browser support.
- Non-standard. Expect poor cross-browser support.
- See implementation notes.
- See implementation notes.