no-cache does not “disable caching”

May 7, 26

One of the most widespread misconceptions about HTTP protocol is that cache-control: no-cache directive disables caching.

TL;DR

Open the Network tab in the browser developer tools and send these two requests:

The second response will be a 304 Not Modified with no actual body sent. The response object with status 200 and body is constructed from the cached response to the first request, although it did contain the no-cache directive.

“Caching”

First of all, “caching” is not an action, it’s a process. Using “caching” as a verb is similar to using “databasing” to refer to database operations.

HTTP caching mechanism consists of two actions:

  1. Store the response in the cache
  2. Use the cached response

So, what does no-cache actually do?

no-cache

a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server.

RFC 2616, section 14.9.1

This means that only the second part of the caching mechanism is disabled. The response will be stored in the cache, but will be used conditionally. See conditional GET.

The directive that effectively disables the caching mechanism is no-store 14.9.2.

Practical application

Task: Use CDN to serve media content with authorization.

Solution:

GET /media/image.jpg
authorization: Bearer <token>
200 OK
etag: "6cddee68f6d246"
cache-control: public, no-cache
  • public directive allows the response to be used by the CDN, even though the request contains the authorization header 14.8.
  • no-cache directive forbids using the response without revalidation with the origin server.

As the result, CDN will send the request to the origin server, which will check the authorization header and return empty 304 response allowing CDN to use previously stored response.

Appendix

The same applies to max-age=0 directive. This section in the Vercel CDN docs is completely wrong:

The default value is cache-control: public, max-age=0, must-revalidate which instructs both the CDN and the browser not to cache.

No it doesn’t. Responses will be stored in the CDN and browser cache. And if you’re dealing with personal, financial, health, or other sensitive data, you must know that.