Перейти к содержимому
Skip to content
← All articles

HTTP Caching Guide: Cache-Control, ETag, Expires

Why HTTP Caching Matters

HTTP caching is one of the most effective ways to speed up website loading. When a browser stores a local copy of a resource, subsequent requests are served instantly without contacting the server. This reduces server load, saves bandwidth, and dramatically improves user experience.

According to Google, reducing load time by 100ms increases conversions by 1%. Properly configured caching can reduce repeat visit load times by 80-90%.

Core Caching Headers

Cache-Control

The Cache-Control header is the primary caching mechanism in HTTP/1.1 and beyond. It supersedes the deprecated Pragma header and takes priority over Expires.

Key directives:

Example for static assets with content hash:

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

Example for HTML pages:

Cache-Control: no-cache

Example for API документацию with private data:

Cache-Control: private, no-store

ETag (Entity Tag)

An ETag is a unique identifier for a specific version of a resource. The server generates a hash of the content and sends it in the response header:

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

On subsequent requests, the browser sends If-None-Match with the stored ETag. If the resource hasn't changed, the server responds with 304 Not Modified without a body, saving bandwidth.

Two types of ETags exist:

Last-Modified and If-Modified-Since

The Last-Modified header contains the date when the resource was last changed. It's a simpler validation mechanism than ETag but less precise — accuracy is limited to one second.

Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT

On subsequent requests, the browser sends If-Modified-Since. ETag takes priority over Last-Modified when both are present.

Expires

A legacy HTTP/1.0 header that sets an absolute expiration date:

Expires: Thu, 01 Dec 2026 16:00:00 GMT

Problems with Expires: depends on client-server clock synchronization, less flexible than Cache-Control. Use Cache-Control: max-age instead.

Caching Strategies by Resource Type

HTML Documents

HTML pages typically reference CSS and JS files, so they should always check for freshness:

Cache-Control: no-cache
ETag: "page-v42"

This allows the browser to cache the page but check for updates on every visit.

CSS, JavaScript, Fonts

Static resources with a hash in the filename (e.g., app.a1b2c3.js) can be cached indefinitely:

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

Without a filename hash, use a shorter TTL:

Cache-Control: public, max-age=86400

Images

Images rarely change. For optimized images with unique URLs:

Cache-Control: public, max-age=2592000

That's 30 days — a good balance between caching and the ability to update.

API Responses

For APIs with frequently changing data:

Cache-Control: private, no-cache, max-age=0

For rarely updated public APIs:

Cache-Control: public, max-age=300, s-maxage=600

Common Mistakes

How to Verify Your Caching Setup

Check your website's caching headers using the Enterno.io HTTP Checker. The tool displays all response headers including Cache-Control, ETag, Expires, and Last-Modified, helping you verify everything is configured correctly.

In Chrome DevTools, the Network tab's Size column shows (disk cache) or (memory cache) for cached resources, and a 304 status code for successfully revalidated ones.

Recommended nginx Configuration

# HTML — always revalidate
location ~* \.html$ {
    add_header Cache-Control "no-cache";
}

# Hashed static assets — cache forever
location ~* \.(js|css)$ {
    add_header Cache-Control "public, max-age=31536000, immutable";
}

# Images — cache for 30 days
location ~* \.(jpg|jpeg|png|gif|webp|svg|ico)$ {
    add_header Cache-Control "public, max-age=2592000";
}

# Fonts — cache for 1 year
location ~* \.(woff2?|ttf|eot)$ {
    add_header Cache-Control "public, max-age=31536000, immutable";
    add_header Access-Control-Allow-Origin "*";
}

Summary

Proper HTTP caching is a balance between speed and content freshness. Use Cache-Control as your primary tool, ETag for validation, and file versioning for safe long-term caching. Regularly check your resource headers to ensure everything is configured correctly.

Check your website right now

Check now →
More articles: HTTP
HTTP
X-Forwarded-For Header: Understanding Client IP Behind Proxies
16.03.2026 · 12 views
HTTP
Analyzing Server Response Headers: What They Reveal About a Website
11.03.2026 · 12 views
HTTP
HTTP Status Codes: Complete Reference with Examples
10.03.2025 · 22 views
HTTP
HTTP/2 vs HTTP/3: What's New and Why Upgrade
14.03.2026 · 12 views