Web Development

Cache-Control Header: Directives and Usage Guide

Configure Cache-Control headers to manage asset storage. Specify how max-age, no-cache, and public directives optimize site speed and server load.

5.4k
cache-control
Monthly Search Volume
Keyword Research

Cache-Control is a set of instructions used in HTTP headers to dictate how web browsers and shared caches (like CDNs) store and reuse website files. It defines whether a resource should be saved, how long it remains valid, and when the browser must check the server for updates. Properly configuring these rules ensures your audience sees the most recent content without sacrificing site speed.

What is Cache-Control?

Cache-Control is an HTTP header consisting of key-value pairs called "directives." These directives appear in both server responses and client requests to manage how files—including images, scripts, and HTML—are stored for future use.

The header uses a comma-separated syntax. For example, Cache-Control: max-age=3600, public tells a browser and a CDN that they can store a file for exactly one hour. If a directive requires an argument, it is joined by an equals sign, usually as an integer.

Why Cache-Control matters

Effective caching directly impacts how users experience your site and how search engines crawl it.

  • Page speed improvement: Loading resources from a local browser cache is significantly faster than fetching them from a server, which helps meet Core Web Vitals thresholds.
  • Reduced server load: Correct headers prevent unnecessary requests to your origin server, saving bandwidth and infrastructure costs.
  • Data security: Directives like private prevent sensitive user data—such as banking details or login sessions—from being stored in public caches like CDNs.
  • Content freshness: It allows you to force a browser to check for new versions of dynamic content, ensuring users do not see outdated information.
  • Bandwidth conservation: Reusing files locally reduces the total data transferred between the server and the end user.

How Cache-Control works

When a browser requests a page, the server sends back a response. If that response includes a Cache-Control header, the browser follows those specific rules to determine if it should store the file in its "private" local cache.

If a shared cache, such as a CDN, exists between the user and the server, it also reads these headers. It may store a "fresh" copy to serve to other users, reducing the distance the data travels.

The Freshness Lifecycle

  1. Fresh: The resource is within its allowed lifespan (TTL) and the browser reuses it instantly.
  2. Stale: The lifespan has expired. The browser cannot use the file as-is and must perform revalidation.
  3. Revalidation: The browser sends a small request to the server asking if the file has changed. If the server says "no" (a 304 Not Modified response), the browser marks the file as fresh again.

Types of Cache-Control directives

Directives are split between those sent by the server (response) and those sent by the browser (request).

Directive Type Functional Goal
max-age Both Sets the lifespan in seconds (e.g., 3600 for one hour).
no-cache Both Forces the browser to validate with the server before every use.
no-store Both Disables all caching; the file must be redownloaded every time.
public Response Allows both browsers and shared CDNs to store the file.
private Response Limits caching to the user's browser only; no CDNs allowed.
s-maxage Response Sets the lifespan specifically for shared caches (CDNs), overriding max-age.
immutable Response Indicates the file will never change while fresh, stopping reloads.

Best practices

Use cache-busting for static assets. For CSS or JavaScript files that change occasionally, include a version hash in the filename. This allows you to set a very long max-age (like one year) because any update to the file will create a new URL, forcing the browser to download the new version immediately.

Apply the 10% rule for heuristic caching. If you do not specify an expiration time, some caches estimate one based on the Last-Modified header. [A recommended benchmark for this estimate is 10% of the time since the file was last changed] (RFC 9111).

Always specify "private" for personalized content. If a page displays user-specific data, mark it as private. This prevents a CDN from accidentally serving one user's personal dashboard to another visitor.

Explicitly define rules for dynamic content. Do not leave caching to chance. For pages that update frequently, use no-cache to ensure the browser always checks for the latest version while still benefiting from 304 Not Modified responses.

Common mistakes

Mistake: Confusing no-cache with no-store. Fix: Use no-cache if you want the browser to store the file but check for updates before using it. Use no-store only when you want to prevent the file from ever being saved to a disk (e.g., for highly sensitive data).

Mistake: Using max-age=0 to prevent all caching. Fix: [While browsers historically used max-age=0 as a workaround for older caches that did not support no-cache, it can still allow stale responses if the server is disconnected] (MDN). Use no-cache or no-store for modern reliability.

Mistake: Forgetting the Vary header. Fix: Use the Vary header alongside Cache-Control when content changes based on the user agent or language. This prevents a mobile user from receiving a cached desktop version of a page.

Examples

Static Resource (Images/CSS)

Cache-Control: public, max-age=31536000, immutable This tells all caches to store the file for one year and not to check for updates even if the user refreshes the page.

Sensitive Dashboard

Cache-Control: private, no-store This ensures the browser never saves the file to the disk and a CDN never sees it.

Frequently Updated Homepage

Cache-Control: no-cache The browser stores the HTML but sends a quick request to the server every time to see if a newer version exists before displaying it.

FAQ

Does Cache-Control affect SEO? Yes, indirectly. Core Web Vitals, specifically Largest Contentful Paint (LCP), are influenced by how fast resources load. Effective caching reduces latency, which can lead to better rankings and a lower bounce rate.

What happens if I have both max-age and Expires? If both are present, max-age takes precedence. Expires is an older header that uses an absolute date (e.g., Sat, 13 May 2023) whereas max-age uses a relative time in seconds.

Can I clear a remote CDN cache using Cache-Control? No. Cache-Control directives manage future behavior. To clear files already stored on a CDN or intermediate server, you must use that provider's specific "purge" or "invalidation" tool.

What is "revalidation"? Revalidation is a "conditional request." The browser sends a token (like an ETag) to the server. If the version on the servant matches the token, the server sends a 304 status code without the bulk of the file, saving time and data.

Start Your SEO Research in Seconds

5 free searches/day • No credit card needed • Access all features