Cache-Control Header Cheat Sheet for Static Assets, HTML, and APIs
cache-controlhttp-headersbrowser-cacheapi-cachingcdn-cachingwebsite-caching

Cache-Control Header Cheat Sheet for Static Assets, HTML, and APIs

CCaching.Website Editorial Team
2026-06-08
10 min read

A practical Cache-Control cheat sheet for static assets, HTML, and APIs, with safe defaults and real-world caching guidance.

Cache-Control is one of the most important headers in website caching, but it is also one of the easiest to overcomplicate. This reference is designed to help developers, operators, and performance-minded site owners choose practical cache headers for static assets, HTML, and APIs without guessing. Use it as a durable cheat sheet: start with the common patterns, understand the tradeoffs, then adapt the policy to your browser cache, CDN caching, and origin behavior.

Overview

This article maps common content types to sensible Cache-Control directives. It is not a full HTTP specification walkthrough. Instead, it focuses on decisions teams repeatedly face in production: how long to cache versioned assets, when HTML should be revalidated, how to avoid serving private content from shared caches, and when API responses should be considered cacheable at all.

At a high level, the Cache-Control header tells browsers and intermediary caches how a response may be stored, reused, and revalidated. In practice, that means it affects browser caching headers, CDN caching, reverse proxies, and sometimes application-level assumptions about freshness. A good policy reduces bandwidth, lowers origin load, improves repeat view speed, and helps reduce TTFB for cache hits. A bad policy creates stale pages, broken deployments, or leaked personalized content.

The safest evergreen rule is simple: cache aggressively only when the content is truly safe to reuse, and pair long cache lifetimes with versioned URLs so old copies can be left in place while new copies are fetched under a new path or filename.

Quick cheat sheet

  • Versioned static assets such as app.abc123.css, main.9f8e7d.js, and hashed images: Cache-Control: public, max-age=31536000, immutable
  • Unversioned static assets that may change at the same URL: Cache-Control: public, max-age=3600 or a similarly modest TTL
  • HTML for frequently updated pages: Cache-Control: public, max-age=0, must-revalidate or no-cache when revalidation is required before reuse
  • Personalized HTML for logged-in users, carts, or dashboards: Cache-Control: private, no-store or at minimum avoid shared caching
  • Public API responses that change on a schedule: Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=30 if your CDN supports it
  • Sensitive API responses containing user-specific or confidential data: Cache-Control: no-store
  • File downloads with stable content: Cache-Control: public, max-age=86400 or longer if versioned

These defaults are starting points, not universal law. The right TTL settings depend on release frequency, personalization, security sensitivity, and whether you control invalidation at the CDN or origin.

Core concepts

Before applying a cache-control cheat sheet, it helps to separate three ideas that often get mixed together: who may store the response, how long it may be reused, and whether the cached copy must be revalidated before use.

Who may cache the response

  • public: the response may be stored by browsers and shared caches such as CDNs and proxies.
  • private: the response is intended for one user and should not be stored by shared caches.
  • no-store: do not store the response at all. OWASP guidance treats this as the safest choice for sensitive data.

For ecommerce and managed WordPress hosting environments, this distinction matters. Product images and theme CSS are usually fine for shared caching. Account pages, checkout flows, and personalized recommendations are not.

How long the response stays fresh

  • max-age: how long, in seconds, a cached response is fresh for browsers and caches unless overridden.
  • s-maxage: a freshness lifetime specifically for shared caches such as CDNs, often useful when browser and edge caching should differ.

A common pattern in CDN caching is to keep a short browser TTL and a longer edge TTL. For example, an API response could be revalidated every minute by the browser but reused for five minutes by the CDN, reducing origin load while keeping end users reasonably current.

Whether reuse requires revalidation

  • no-cache: a cache may store the response, but it must revalidate before using it again.
  • must-revalidate: once stale, the response should not be reused without successful revalidation.
  • immutable: the response is expected not to change during its freshness lifetime. Best used for versioned static assets.

One common misunderstanding is treating no-cache as meaning “do not cache.” It does not. It means “store if you want, but check before reuse.” If you truly do not want the response stored, use no-store.

Practical policy by content type

1. Versioned static assets

Examples: hashed CSS, JavaScript bundles, icon files, font files, and fingerprinted images generated during deployment.

Recommended baseline:

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

This is the classic high-performance setup for website speed optimization. Because the filename changes when the file changes, you can cache it for a year without worrying about stale content. This pattern works especially well with CDN caching, Cloudflare cache rules, and asset pipelines in modern frameworks.

2. Unversioned static assets

Examples: /logo.png, /styles.css, or a script loaded at a stable path that may be updated in place.

Recommended baseline:

Cache-Control: public, max-age=3600

If the URL does not change when the file changes, avoid very long TTLs unless you have reliable purge and invalidation workflows. A one-hour TTL is often easier to live with than a one-year mistake.

3. Public HTML pages

Examples: homepages, marketing pages, documentation pages, category pages, and many blog posts.

Recommended baseline:

Cache-Control: public, max-age=0, must-revalidate

or

Cache-Control: no-cache

These settings are useful when HTML can be stored but should be checked before reuse. In practice, many stacks combine this with ETag or Last-Modified handling. Browser and proxy behavior can vary, so test with your actual CDN and server caching setup.

4. Personalized or authenticated HTML

Examples: account pages, admin screens, carts, checkout, subscription dashboards, and member-only content.

Recommended baseline:

Cache-Control: private, no-store

This is the conservative choice and often the right one. In WordPress caching, WooCommerce caching, and membership systems, serving a shared cached copy of private content is a serious risk. Some teams relax this to private, no-cache in narrow cases, but only after careful review.

5. Public API responses

Examples: exchange rates, catalog data, search suggestions, non-sensitive configuration, or content feeds.

Recommended baseline:

Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=30

This is a practical edge caching pattern where the browser gets a short freshness window and the CDN can absorb more traffic. Whether stale-while-revalidate is honored depends on the caching layer, so confirm behavior in your stack.

6. Private or sensitive API responses

Examples: user profiles, billing data, admin APIs, tokens, or anything confidential.

Recommended baseline:

Cache-Control: no-store

This aligns with the conservative security recommendation in OWASP material for sensitive data. If a response should not sit in browser cache, intermediary cache, or local storage controlled by the HTTP cache, no-store is the cleanest instruction.

7. Downloads and media files

Examples: PDFs, public datasets, installer packages, and stable images.

Recommended baseline:

Cache-Control: public, max-age=86400

Use a longer TTL if the file is versioned or released at a unique URL. Use a shorter one if the path is reused.

This topic becomes easier when related cache terms are kept distinct.

ETag and Last-Modified

These validators support revalidation. They do not replace Cache-Control; they complement it. A response with no-cache often relies on a validator so the client can ask whether the cached copy is still current instead of downloading the whole resource again.

TTL settings

TTL simply means time to live. In browser caching headers and CDN rules, TTL settings determine how long something remains fresh before revalidation or expiry. Teams often use one TTL at the browser, another at the CDN, and another for application object caches such as Redis object cache.

Page cache vs object cache

A page cache stores a full rendered response, often HTML. An object cache stores reusable application data such as query results, fragments, or computed objects. Cache-Control affects HTTP caching, not your internal Redis object cache directly. Still, the layers interact. Strong HTTP caching can hide origin slowness, while a good object cache can make unavoidable origin requests much cheaper.

Server caching and reverse proxy caching

Technologies such as NGINX FastCGI cache, Varnish cache, and some managed WordPress hosting page caches operate between the application and the visitor. They may follow origin cache headers, override them, or layer additional rules on top. That is why a sound origin header policy should be paired with explicit tests at the edge and server layers.

CDN cache rules and edge caching

CDN vendors can cache content even when origin headers are conservative, depending on rules you configure. That is useful, but it can also create surprises. If your origin sends private or no-store, avoid edge rules that force caching unless you are absolutely sure the response is safe for shared reuse.

Security boundary

Cache headers are performance tools, but they also define handling for sensitive responses. The OWASP guidance is a useful boundary marker here: if the data is sensitive, default to no-store. Performance optimization should not weaken privacy or confidentiality.

Practical use cases

Below are common production scenarios and the policy choices that usually hold up well over time.

Marketing site behind a CDN

If the site consists mostly of public pages and versioned assets, the simplest approach is to cache assets aggressively and require HTML revalidation.

  • CSS and JS bundles: public, max-age=31536000, immutable
  • Images with content hashes: same as above
  • HTML pages: public, max-age=0, must-revalidate

This gives you strong repeat-view performance without forcing users to wait for stale HTML to expire naturally after a deployment.

WordPress site with frequent content edits

WordPress caching often combines browser cache rules, page cache, and plugin-level behavior. For many editorial sites:

  • Theme assets with version strings or hashed filenames: long-lived cache
  • Post and archive HTML: revalidate frequently or use short TTLs
  • Logged-in admin and preview traffic: do not share-cache

If you are also using LiteSpeed Cache, NGINX FastCGI cache, or Varnish cache, check whether those layers honor origin headers as expected.

WooCommerce or other ecommerce storefronts

Catalog pages and product images are often good candidates for shared caching. Cart, checkout, and account pages are not. Be explicit:

  • Public catalog HTML: cache carefully, usually with revalidation or a short TTL
  • Static assets: long-lived if versioned
  • Cart and checkout: private, no-store
  • Account APIs: no-store

This is one of the clearest examples of why website caching needs content-aware rules rather than one global policy.

Public API consumed by web and mobile clients

For APIs with mostly shared data, use short browser freshness and a somewhat longer shared-cache policy. That often lowers origin traffic while keeping data timely enough for users. If the API powers dashboards or near-real-time views, keep TTLs short and test carefully. For more on multilayer designs, see Designing cache layers for high-velocity telemetry.

Edge-heavy deployments

When using aggressive edge caching, align Cache-Control with your purge strategy. If content is difficult to purge reliably, shorten TTLs. If invalidation is automated and dependable, you can be more assertive. Related operational tradeoffs are explored in Edge vs central caching for real-time industrial monitoring and Edge caching to cut carbon.

A practical rollout checklist

  1. Group responses by behavior: versioned static, unversioned static, public HTML, personalized HTML, public API, sensitive API.
  2. Set a default header policy per group.
  3. Confirm whether your CDN, reverse proxy, and application framework override origin headers.
  4. Test with real requests using browser devtools and command-line inspection.
  5. Deploy invalidation rules before extending TTLs.
  6. Review private routes separately, especially for authenticated sessions.

When to revisit

A good cache policy is not “set and forget.” Revisit this topic when any of the inputs behind freshness, safety, or invalidation change.

Revisit after deployment workflow changes

If your build pipeline moves from unversioned assets to hashed filenames, you can safely increase cache duration for static assets. If the reverse happens, lower TTLs immediately.

Revisit after CDN or hosting changes

Moving to a different web hosting stack, CDN, or managed WordPress hosting platform can change how cache headers are interpreted. Some providers add their own cache rules, edge caching defaults, or HTML caching behavior.

Revisit when content becomes personalized

A route that was once public may later include user-specific elements such as names, balances, carts, or recommendations. That shift should trigger a review of public versus private and whether no-store is now required.

Revisit when API expectations change

If clients now expect fresher data, lower your TTL settings or increase revalidation. If the API is under heavier load and freshness tolerance is broader, you may be able to push more caching to the edge.

Revisit when debugging performance or correctness

If you are trying to reduce TTFB, improve Core Web Vitals, or explain inconsistent content updates, inspect your cache headers before changing infrastructure. Many apparent server caching problems are really policy mismatches across browser, CDN, and origin.

Action steps to keep this cheat sheet useful

  • Document your standard headers for each content type in the repository or runbook.
  • Test cache behavior in staging with the same CDN and proxy rules used in production.
  • Pair long-lived asset caching with versioned URLs every time.
  • Use no-store for sensitive responses unless you have a strong reason not to.
  • Audit authenticated routes regularly for accidental shared caching.
  • Recheck policies whenever platform behavior, terminology, or browser support meaningfully shifts.

If you want one durable rule to remember, make it this: long cache lifetimes belong to stable, versioned public resources; sensitive and user-specific responses should be treated conservatively; and everything else should be tested in the real path from browser to CDN to origin.

Related Topics

#cache-control#http-headers#browser-cache#api-caching#cdn-caching#website-caching
C

Caching.Website Editorial Team

Senior SEO Editor

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.

2026-06-10T00:06:48.892Z