Caching Static Assets (CSS, JS, Images)

Best practices for caching static assets with long max-age, content hashing, and the immutable directive. Maximize cache hit rates while enabling instant updates.

Use Cases

Detailed Explanation

Static Asset Caching Strategy

Static assets (CSS, JavaScript, images, fonts, videos) are the easiest resources to cache aggressively because they change only when you deploy new code.

The Recommended Header

Cache-Control: public, max-age=31536000, immutable

This tells every cache (browser, CDN, proxy): "Cache this for 1 year and don't even revalidate on reload."

Why 1 Year?

31536000 seconds (365 days) is the maximum recommended value per RFC 2616. In practice, browser caches are limited in size and may evict entries sooner, but setting 1 year ensures the resource stays cached as long as possible.

Content Hashing Makes It Safe

Modern build tools generate filenames with content hashes:

app-BkQ3x9f2.js        (Vite)
app.a1b2c3d4.chunk.js   (webpack)
styles-Hx8n4p1m.css     (esbuild)

When you change the source code, a new hash is generated, producing a new filename. The old file at the old URL never changes — so max-age=31536000 is perfectly safe.

Implementation by File Type

File Type Header Notes
Hashed JS/CSS public, max-age=31536000, immutable Content-hash filename
Unhashed JS/CSS public, max-age=0, must-revalidate Requires ETag support
Images (hashed) public, max-age=31536000, immutable Content-hash filename
Images (unhashed) public, max-age=86400 Accept 1-day staleness
Fonts public, max-age=31536000, immutable Rarely change
Favicon public, max-age=86400 Changes are rare but possible

Server Configuration (Nginx)

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
    add_header Cache-Control "public, max-age=31536000, immutable";
}

Use Case

A production React application serves 2MB of JavaScript and CSS bundles. With 'public, max-age=31536000, immutable', returning users load the app from cache in under 100ms. New deployments change the content hash, so users automatically download the new version on their next visit. This setup reduces CDN bandwidth by 95% for returning visitors and makes the app feel instant on repeat visits.

Try It — Cache-Control Builder

Open full tool