Skip to content

How to Configure Cache Headers for Your Site

Key idea:

Cache-Control is an HTTP header controlling browser and CDN caching. For immutable assets (JS/CSS/images with hash) — public, max-age=31536000, immutable (1 year). For HTML — public, max-age=60, stale-while-revalidate=86400. For APIs — no-store. Correct config speeds up repeat visits by 30-80%.

Below: step-by-step, working examples, common pitfalls, FAQ.

Check your site →

Step-by-Step Setup

  1. Identify resource type: immutable asset (hashed name) / HTML / API / user data
  2. For immutable (app.a8f3c.js): Cache-Control: public, max-age=31536000, immutable
  3. For HTML homepage: Cache-Control: public, max-age=60, s-maxage=600
  4. For APIs: Cache-Control: no-store (personal data) or private, max-age=0, must-revalidate
  5. Add ETag or Last-Modified for conditional requests (304 Not Modified)
  6. Verify with Enterno HTTP Checker — shows all response headers
  7. In DevTools → Network → inspect size and "(from cache)" / "(disk cache)" / "(memory cache)"

Working Examples

ScenarioConfig / Record
nginx: static with hash (1 year)location ~* \.(js|css|png|jpg|woff2)$ { add_header Cache-Control "public, max-age=31536000, immutable"; }
nginx: HTML (short cache)location / { add_header Cache-Control "public, max-age=60, s-maxage=600"; }
Apache: .htaccess static<FilesMatch "\.(js|css|png|jpg|woff2)$"> Header set Cache-Control "public, max-age=31536000, immutable" </FilesMatch>
API (no-cache)Cache-Control: no-store, no-cache, must-revalidate
CDN-aware (CDN caches, browser does not)Cache-Control: public, max-age=0, s-maxage=86400

Common Pitfalls

  • Caching HTML for 1 year — new posts invisible to visitors until cache clears
  • No immutable on hashed static assets — browser sends pointless If-None-Match each time
  • Cache-Control: no-cache ≠ "don't cache". It means "always revalidate". Use no-store
  • Private data in a public CDN cache = cross-user leak (critical bug)
  • Not updating cache headers after CDN purge — stale assets stick in browsers

TL;DR: Setting Cache-Control Headers

To set Cache-Control headers effectively, use the HTTP response header to dictate how, and for how long, browsers cache your web resources. For example, to cache static assets for one week, apply the header Cache-Control: public, max-age=604800. This guide provides comprehensive steps for configuring Cache-Control headers across various platforms, including Nginx, Apache, and Node.js.

Understanding Cache-Control Directives

The Cache-Control HTTP header is crucial for managing the caching behavior of web resources. This header can significantly impact the performance and efficiency of your web applications. In this section, we will explore the various directives available in the Cache-Control header, their implications, and best practices for implementation.

Common Cache-Control Directives

  • public: Indicates that the response may be cached by any cache, even if it is normally non-cacheable.
  • private: This directive specifies that the response is intended for a single user and should not be stored by shared caches.
  • no-cache: Forces caches to submit the request to the origin server for validation before serving a cached copy.
  • no-store: Instructs caches not to store any part of the request or response.
  • max-age: Defines the maximum amount of time a resource is considered fresh. For example, max-age=3600 means the resource is fresh for one hour.
  • must-revalidate: Indicates that once the resource becomes stale, it must not be used without successful validation on the origin server.

Understanding these directives allows you to tailor your caching strategy according to your website's needs. For example, if you have static assets that change infrequently, you may want to set a longer max-age value to reduce server load and improve load times for users.

Best Practices for Implementing Cache-Control

When setting Cache-Control headers, consider the following best practices:

  1. Assess Resource Types: Differentiate between static resources (like images and stylesheets) and dynamic content (like HTML pages) to apply appropriate caching strategies.
  2. Use Versioning: For static assets, consider implementing versioning in URLs (e.g., style.v1.css) to ensure users receive the latest version after updates.
  3. Monitor Performance: Regularly review your caching strategy by analyzing performance metrics and user behavior to adjust Cache-Control headers as necessary.

In the next section, we will provide practical examples for setting Cache-Control headers on various web servers, including Nginx and Apache. These examples will help you implement the directives discussed here effectively.

Learn more

Frequently Asked Questions

Difference between max-age and s-maxage?

<code>max-age</code> — TTL for private caches (browser). <code>s-maxage</code> — TTL for shared caches (CDN, proxy). If both are set — each cache uses its own.

What is immutable?

A Cache-Control directive: "this resource will never change". The browser skips revalidation (If-None-Match) even on reload. Important for hash-based assets.

Do I need ETag if I have Cache-Control?

Yes. Cache-Control says "cache is valid for N seconds". ETag is used at expiry for 304 Not Modified (conditional requests). They complement each other.

How do I inspect my site's cache strategy?

<a href="/en/check">Enterno HTTP Checker</a> → enter URL → Cache section shows Cache-Control, ETag, Age, max-age.

Try the live tool that powered this guide

Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.