What a browser cache does

A browser cache stores eligible responses so the browser can use them again. If a visitor reloads a page that uses the same stylesheet, for example, the browser may be able to read its stored copy rather than download the entire file. Caching can reduce transferred data and waiting time, especially for resources used across multiple pages.

Two decisions matter: whether a response may be stored, and whether a stored response is fresh enough to use without contacting the server. A response that is no longer fresh is not necessarily discarded. The browser may ask the server whether its copy is still valid. This check is called revalidation.

Caches also need to identify which stored response matches a request. The URL is central, but other details can matter. A server can use the Vary response header to indicate that a response depends on a request header, such as Accept-Encoding. A matching URL alone therefore does not always mean a cached response can be used.

Cache-Control sets the reuse rules

Cache-Control is a response header that tells caches how to handle a response. Cache-Control: max-age=3600, for instance, allows a cache to treat the response as fresh for up to 3,600 seconds under normal conditions. During that period, a matching fresh copy can generally be used without checking with the server. Afterward, the copy becomes stale and ordinarily needs revalidation before reuse.

Some directives answer different questions. no-cache permits storage but requires the cache to validate the response before using it. Despite its name, it does not mean “never store this.” no-store tells caches not to store the response. private limits storage to a private cache, such as a browser cache, rather than a shared cache. public explicitly permits storage by shared caches when other rules allow it.

Choose a policy based on how a resource changes. A versioned stylesheet whose URL changes whenever its contents change can usually have a longer freshness lifetime than an HTML page whose contents may change at the same URL. For a response that should always be checked before reuse, no-cache can be more appropriate than a long max-age. Avoid relying on caching alone to protect sensitive content; access control and careful handling of private data remain separate concerns.

ETags identify a stored version

An ETag is a response header containing a server-chosen identifier for a representation of a resource. A server might return ETag: "version-7" with a response. If the browser later needs to revalidate that stored response, it can send the identifier in an If-None-Match request header. The exact identifier is not important to the browser; it is a value the server can compare with the current version.

If the server determines that the browser’s version still matches, it can return 304 Not Modified rather than sending the response body again. The browser can then use its stored body, subject to the applicable cache rules. If the resource has changed, the server can instead send a new response with its body and updated caching headers. Revalidation still requires a network exchange, but a 304 response avoids transferring the full resource body.

ETags do not make a response permanently fresh. They help answer the question “Has this changed?” when a cache needs to check. Servers may generate them in different ways, and an ETag should not be assumed to be a human-readable version number or a checksum.

Follow a typical request cycle

Imagine a browser requests /styles.css and receives a response with Cache-Control: max-age=3600 and an ETag. On a second visit while the response is fresh, the browser can use its stored copy without a request to the server. Once the response is stale, the browser can send a conditional request containing If-None-Match. A 304 response means it can keep using the stored body; a new 200 response supplies a replacement body.

Now imagine the stylesheet changes but keeps the same URL. Visitors whose cached copy is still fresh may continue to use it until its freshness period ends. That is why long lifetimes work best with versioned resource URLs: changing the URL gives the new file a distinct cache entry. For content that changes without a URL change, use a freshness period that fits how quickly visitors need to see updates.

Check behavior in the browser

Browser developer tools can help you inspect a resource’s response headers and the requests made on a repeat visit. Look for Cache-Control and ETag on the response, then check whether a later request includes If-None-Match and receives a 304 status. If no request appears, the browser may have used a fresh cached copy.

Test under ordinary browsing conditions as well as during development. Reload controls and developer-tool settings can change caching behavior, so a forced reload is not a reliable picture of a routine return visit. When results are surprising, check the requested URL, the response’s cache directives, and any Vary header before changing the policy. These details often explain why a resource was fetched, revalidated, or reused.

Back to category ↗