Understanding HTTP Caching

Written by

in

HTTP caching exists to avoid transferring data that the client already has. It operates on two distinct mechanisms, and confusing them is the source of most caching bugs.

Freshness

A response carries a lifetime, usually via Cache-Control: max-age. While the response is within that lifetime it is considered fresh, and a cache may reuse it without contacting the origin server at all. No request is made, so the origin sees nothing.

Validation

Once a response goes stale, the cache does not simply discard it. It asks the origin whether the copy it holds is still good, using a validator it received earlier. If the origin says nothing has changed, the cache reuses its stored copy.

This is where 304 Not Modified comes in. The origin answers with headers only, no body, and the client reuses what it already had. The request still happens — it is just very small.

Why the distinction matters for measurement

A fresh cached response produces no origin request and no log line. A validated response produces a request that appears in the log with status 304. If you are counting crawler activity from origin logs, freshness makes traffic disappear while validation makes it cheap but visible.

Cache-Control directives worth knowing

  • max-age=600 — fresh for ten minutes
  • must-revalidate — once stale, the cache must check before reusing
  • no-cache — may be stored, but must be revalidated every time
  • no-store — must not be stored at all
  • public / private — whether shared caches may store it

Note that no-cache does not mean “do not cache”. That is no-store. The naming is unfortunate and the confusion is common.