195

From the RFC 2616

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1

no-cache

If the no-cache directive does not specify a field-name, then a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server. This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.

So it directs agents to revalidate all responses.

Compared this to

must-revalidate

When the must-revalidate directive is present in a response received by a cache, that cache MUST NOT use the entry after it becomes stale to respond to a subsequent request without first revalidating it with the origin server

So it directs agents to revalidate stale responses.

Particularly with regard to no-cache, is this how user agents actually, empirically treat this directive?

What's the point of no-cache if there's must-revalidate and max-age?

See this comment:

http://palpapers.plynt.com/issues/2008Jul/cache-control-attributes/

no-cache

Though this directive sounds like it is instructing the browser not to cache the page, there’s a subtle difference. The “no-cache” directive, according to the RFC, tells the browser that it should revalidate with the server before serving the page from the cache. Revalidation is a neat technique that lets the application conserve band-width. If the page the browser has cached has not changed, the server just signals that to the browser and the page is displayed from the cache. Hence, the browser (in theory, at least), stores the page in its cache, but displays it only after revalidating with the server. In practice, IE and Firefox have started treating the no-cache directive as if it instructs the browser not to even cache the page. We started observing this behavior about a year ago. We suspect that this change was prompted by the widespread (and incorrect) use of this directive to prevent caching.

Has anyone got anything more official on this?

Update

The must-revalidate directive ought to be used by servers if and only if failure to validate a request on the representation could result in incorrect operation, such as a silently unexecuted financial transaction.

That's something I've never taken to heart until now. The RFC is saying not to use must-revalidate lightly. The thing is, with web services, you have to take a negative view and assume the worst for your unknown client apps. Any stale resource has the potential to cause a problem.

And something else I've just considered, without Last-Modified or ETags, the browser can only fetch the whole resource again. However with ETags, I've observed that Chrome at least seems to revalidate on every request. Which makes both these directives moot or at least poorly named since they can't properly revalidate unless the request also includes other headers that then cause 'always revalidate' anyway.

I just want to make that last point clearer. By just setting must-revalidate but not including either an ETag or Last-Modified, the agent can only get the content again since it has nothing to send to the server to compare.

However, my empirical testing has shown that when ETag or modified header data is included in responses, the agents always revalidate anyway, regardless of the presence of the must-revalidate header.

So the point of must-revalidate is to force a 'bypass cache' when it goes stale, which can only happen when you have set a lifetime/age, thus if must-revalidate is set on a response with no age or other headers, it effectively becomes equivalent to no-cache since the response will be considered immediately stale.

-- So I'm going to finally mark Gili's answer!

Anish B.
  • 7,321
  • 3
  • 12
  • 33
Luke Puplett
  • 36,042
  • 37
  • 161
  • 231
  • So in theory the difference is _validate-always_ vs _validate-if-stale_, whereas in practice no-cache gets treated by certain browsers as the comment you quoted says as _never-validate_ … so you should make your choice of which of those to use based on what caching behavior you actually want to achieve in practice … – CBroe Aug 09 '13 at 14:39
  • Please read http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p6-cache-latest.html and see whether this clarifies things for you. – Julian Reschke Aug 10 '13 at 11:09
  • possible duplicate of [What's the difference between Cache-Control: max-age=0 and no-cache?](http://stackoverflow.com/questions/1046966/whats-the-difference-between-cache-control-max-age-0-and-no-cache) – Joe Sep 15 '14 at 12:37
  • check this decision tree for answer https://stackoverflow.com/a/49925190/3748498 – pravdomil Apr 19 '18 at 15:51

5 Answers5

209

I believe that must-revalidate means :

Once the cache expires, refuse to return stale responses to the user even if they say that stale responses are acceptable.

Whereas no-cache implies :

must-revalidate plus the fact the response becomes stale right away.

If a response is cacheable for 10 seconds, then must-revalidate kicks in after 10 seconds, whereas no-cache implies must-revalidate after 0 seconds.

At least, that's my interpretation.

Anish B.
  • 7,321
  • 3
  • 12
  • 33
Gili
  • 76,473
  • 85
  • 341
  • 624
  • 2
    That's how I'm seeing it now. The interesting part is my last para, without an ETag or Last-Modified, the agent has nothing to use to validate what it has in cache and must download the whole payload again. So when the RFC says "revalidate" that probably means, re-fetch. – Luke Puplett Nov 13 '13 at 11:55
  • 53
    Which also means `max-age=0, must-revalidate` and `no-cache` are identical – Anshul Apr 06 '15 at 07:45
  • 5
    @Anshul, at first I thought you were right that 'max-age=0, must-revalidate and no-cache are identical', but see Jeffrey Fox's answer which seems to indicate that's not quite right. – Don Hatch Jul 15 '16 at 07:13
  • @DonHatch added my comments below in Jeffrey's answer. – Anshul Jul 21 '16 at 11:44
  • 2
    @Anshul No, `must-revalidate` and `no-cache` have different meaning for fresh responses: If a cached response is fresh (i.e, the response hasn't expired), `must-revalidate` will make the proxy serve it right away without revalidating with the server, whereas with `no-cache` the proxy must revalidate the cached response regardless of freshness. Source: "HTTP - The Definitive Guide", pages 182-183. – Matthias Braun Jul 15 '17 at 10:16
  • 2
    @MatthiasBraun, exactly, and that is why `max-age=0` is needed to make `must-revalidate` behave identical to `no-cache` – Anshul Jul 22 '17 at 18:47
  • 1
    @Anshul Oh, I thought you meant that *all three of them* are identical. – Matthias Braun Jul 22 '17 at 19:16
  • 11
    @MatthiasBraun Ah, I can see the source of confusion. May be I should have written _`no-cache` and `max-age=0, must-revalidate` are identical_ – Anshul Jul 27 '17 at 11:33
  • @Anshul Not quite identical according to RFC7234: "in all circumstances a cache MUST obey the **must-revalidate** directive; in particular, if a cache cannot reach the origin server for any reason, it MUST generate a **504 (Gateway Timeout)** response." But **no-cache** is less draconian (no 5xx server error) and may serve a stale resource if for instance a cache cannot connect to the origin server. – Clint Pachl May 27 '21 at 12:33
  • @Anshul But Mozilla states that **Cache-Control: max-age=0** may serve stale resources. I'm going to guess that every caching agent may implement the RFC slightly differently. – Clint Pachl May 27 '21 at 12:40
  • @ClintPachl What Mozilla states does not contradict what Anshul wrote. Mozilla is telling you that so long as you omit `must-revalidate` they may return stale results. If you don't want stale results, make sure to include it. – Gili May 28 '21 at 21:13
27

max-age=0, must-revalidate and no-cache aren't exactly identical. With must-revalidate, if the server doesn't respond to a revalidation request, the browser/proxy is supposed to return a 504 error. With no-cache, it would just show the cached content, which would be probably preferred by the user (better to have something stale than nothing at all). This is why must-revalidate is intended for critical transactions only.

Jeffrey Fox
  • 403
  • 4
  • 4
  • 13
    Not sure about your `no-cache` interpretation. From the [RFC 7234](https://tools.ietf.org/html/rfc7234#section-5.2.2.2) _The "no-cache" response directive indicates that the response MUST NOT be used to satisfy a subsequent request without successful validation on the origin server. This allows an origin server to prevent a cache from using it to satisfy a request without contacting it, even by caches that have been configured to send stale responses._ This sounds similar to restrictions for `must-revalidate` – Anshul Jul 21 '16 at 11:46
  • 12
    Does Jeffrey have evidence that implementations behave how he has described? – OrangeDog Aug 03 '16 at 13:04
  • I think this answer is correct for proxy / lb servers. But indeed, browsers don't return a 504 in that case. – Yann Dìnendal Jan 21 '17 at 07:56
  • So `must-validate` means `must-refresh` – Simon_Weaver Jan 14 '19 at 22:46
  • 1
    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control directly states "`no-cache` and `max-age=0, must-revalidate` indicates same meaning." – jess Feb 03 '21 at 21:49
17

With Jeffrey Fox's interpretation about no-cache, i've tested under chrome 52.0.2743.116 m, the result shows that no-cache has the same behavior as must-revalidate, they all will NOT use local cache when server is unreachable, and, they all will use cache while tap browser's Back/Forward button when server is unreachable. As above, i think max-age=0, must-revalidate is identical to no-cache, at least in implementation.

rogerdpack
  • 50,731
  • 31
  • 212
  • 332
Wilson Zeng
  • 171
  • 1
  • 4
  • Will Chrome use local cache when the server is available to revalidate? (i.e. "If-Modified-Since"). In both cases? – Rich Aug 23 '18 at 09:59
0

Agreed with part of @Jeffrey Fox's answer:

max-age=0, must-revalidate and no-cache aren't exactly identical.

Not agreed with this part:

With no-cache, it would just show the cached content, which would be probably preferred by the user (better to have something stale than nothing at all).

What should implementations do when cache-control: no-cache revalidation failed is just not specified in the RFC document. It's all up to implementations. They may throw a 504 error like cache-control: must-revalidate or just serve a stale copy from cache.

D.jennis
  • 139
  • 1
  • 8
-2

I think there is a difference between max-age=0, must-revalidate and no-cache:

In the must-revalidate case the client is allowed to send a If-Modified-Since request and serve the response from cache if 304 Not Modified is returned.

In the no-cache case, the client must not cache the response, so should not use If-Modified-Since.

Rich
  • 13,254
  • 1
  • 56
  • 102
  • 9
    But `no-cache` does not mean `no-store` - with `no-cache`, the resource can still be cached in the client; it just must be re-validated before being used? – Aron Aug 13 '18 at 16:49
  • 7
    You are conflating `no-cache` and `no-store`. `no-cache` means the resource MUST be **revalidated**. **Revalidate** includes the option to use conditional requests, such as `If-None-Match` and `If-Modified-Since`. – Jules Sam. Randolph Aug 17 '18 at 17:24
  • 1
    @JulesRandolph: you may be right. Do you have any tests / demos? All the conflicting evidence-free assertions on this q are frustrating. Even the accepted answer just says "At least, that's my interpretation". I might set up a test bed and post it here if I get some time. – Rich Aug 23 '18 at 09:58