The header Cache-Control: max-age=0 implies that the content is considered stale (and must be re-fetched) immediately, which is in effect the same thing as Cache-Control: no-cache.
The header Cache-Control: max-age=0 implies that the content is considered stale (and must be re-fetched) immediately, which is in effect the same thing as Cache-Control: no-cache.
In my recent tests with IE8 and Firefox 3.5, it seems that both are RFC-compliant. However, they differ in their "friendliness" to the origin server. IE8 treats no-cache responses with the same semantics as max-age=0,must-revalidate. Firefox 3.5, however, seems to treat no-cache as equivalent to no-store, which sucks for performance and bandwidth usage.
Squid Cache, by default, seems to never store anything with a no-cache header, just like Firefox.
My advice would be to set public,max-age=0 for non-sensitive resources you want to have checked for freshness on every request, but still allow the performance and bandwidth benefits of caching. For per-user items with the same consideration, use private,max-age=0.
I would avoid the use of no-cache entirely, as it seems it has been bastardized by some browsers and popular caches to the functional equivalent of no-store.
Additionally, do not emulate Akamai and Limelight. While they essentially run massive caching arrays as their primary business, and should be experts, they actually have a vested interest in causing more data to be downloaded from their networks. Google might not be a good choice for emulation, either. They seem to use max-age=0 or no-cache randomly depending on the resource.
max-age
When an intermediate cache is forced, by means of a max-age=0 directive, to revalidate
its own cache entry, and the client has supplied its own validator in the request, the
supplied validator might differ from the validator currently stored with the cache entry.
In this case, the cache MAY use either validator in making its own request without
affecting semantic transparency.
However, the choice of validator might affect performance. The best approach is for the
intermediate cache to use its own validator when making its request. If the server replies
with 304 (Not Modified), then the cache can return its now validated copy to the client
with a 200 (OK) response. If the server replies with a new entity and cache validator,
however, the intermediate cache can compare the returned validator with the one provided in
the client's request, using the strong comparison function. If the client's validator is
equal to the origin server's, then the intermediate cache simply returns 304 (Not
Modified). Otherwise, it returns the new entity with a 200 (OK) response.
If a request includes the no-cache directive, it SHOULD NOT include min-fresh,
max-stale, or max-age.
courtesy: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4
Don't accept this as answer - I will have to read it to understand the true usage of it :)
I'm hardly a caching expert, but Mark Nottingham is. Here are his caching docs. He also has excellent links in the References section.
Based on my reading of those docs, it looks like max-age=0 could allow the cache to send a cached response to requests that came in at the "same time" where "same time" means close enough together they look simultaneous to the cache, but no-cache would not.
One thing that (surprisingly) hasn't been mentioned is that a request can explicitly indicate that it will accept stale data, using the max-stale directive. In that case, if the server responded with max-age=0, the cache would merely consider the response stale, and would be free to use it to satisfy the client's request [which asked for potentially-stale data]. By contrast, if the server sends no-cache that really does trump any request by the client (with max-stale) for stale data, as the cache MUST revalidate.
This is answered directly in the MDN docs about cache control:
Most HTTP/1.0 caches don't support
no-cachedirectives, so historicallymax-age=0was used as a workaround. But onlymax-age=0could cause a stale response to be reused when caches disconnected from the origin server.must-revalidateaddresses that. That's why the example below is equivalent tono-cache.Cache-Control: max-age=0, must-revalidateBut for now, you can simply use
no-cacheinstead.
And also in the MDN docs about cache validation:
It is often stated that the combination of
max-age=0andmust-revalidatehas the same meaning asno-cache.Cache-Control: max-age=0, must-revalidate
max-age=0means that the response is immediately stale, andmust-revalidatemeans that it must not be reused without revalidation once it is stale — so in combination, the semantics seem to be the same asno-cache.However, that usage of
max-age=0is a remnant of the fact that many implementations prior to HTTP/1.1 were unable to handle theno-cachedirective — and so to deal with that limitation,max-age=0was used as a workaround.But now that HTTP/1.1-conformant servers are widely deployed, there's no reason to ever use that
max-age=0-and-must-revalidatecombination — you should instead just useno-cache.