Cache-Control Header Generator
Build a correct Cache-Control HTTP header
visually. Pick directives, set max-age in any unit, and copy ready-to-paste Nginx, Apache,
Express, or CDN snippets.
Quick Presets
Directives
= 3600 seconds · 1h
Output
Header Value
public, max-age=3600
Full HTTP Header
Cache-Control: public, max-age=3600
Nginx
add_header Cache-Control "public, max-age=3600" always;
Apache (.htaccess)
Header set Cache-Control "public, max-age=3600"
Express / Node.js
res.setHeader('Cache-Control', 'public, max-age=3600');Fastify
reply.header('cache-control', 'public, max-age=3600');Fetch / Worker Response
new Response(body, {
headers: { 'Cache-Control': 'public, max-age=3600' }
});Cloudflare Page Rule
# Cloudflare Page Rule / Transform Rule Cache-Control: public, max-age=3600
HTML <meta> tag
<meta http-equiv="Cache-Control" content="public, max-age=3600" />
About the Cache-Control Header Generator
The Cache-Control Header Generator builds the HTTP Cache-Control response header by composing directives from RFC 9111 (the HTTP caching specification) and the
RFC 5861 stale-content extensions. Every directive is exposed as a checkbox or input, the
final header updates live as you change it, and you can copy ready-to-paste snippets for the
most common origin servers and CDNs.
Cache-Control is the single most important
header for web performance and correctness. It tells browsers, intermediate proxies, and CDNs
whether they can store a response, for how long, what to do when it goes stale, and whether
to serve it to authenticated users. The wrong header makes pages slow (no CDN cache), or
worse, leaks one user's response to another (private content cached publicly).
The generator runs entirely in your browser. Nothing is uploaded — your URLs, headers, and tweaks stay on your device.
Directive Cheat Sheet
| Directive | Effect |
|---|---|
| public | Any cache (browser, proxy, CDN) may store the response. |
| private | Only the user's browser cache may store it. CDNs and shared proxies must skip storage. |
| no-cache | Caches may store it but must revalidate with the origin every time before reuse. |
| no-store | No cache may store the response in any form. Use for highly sensitive responses. |
| max-age=N | Fresh for N seconds in any cache. Most common directive. |
| s-maxage=N | Fresh for N seconds in shared caches (CDN / proxy) only — overrides max-age there. |
| immutable | Promise that the body will not change while fresh — browsers skip the revalidation request on reload. |
| must-revalidate | Once stale, the response must not be served without revalidating with the origin. |
| proxy-revalidate | Same as must-revalidate, but only applies to shared caches. |
| stale-while-revalidate=N | Serve a stale response for up to N more seconds while a background revalidation runs. |
| stale-if-error=N | If revalidation fails (5xx, network error), keep serving stale for up to N seconds. |
| no-transform | Forbid intermediaries from re-encoding the body (image proxies, mobile data savers). |
How to Use the Cache-Control Header Generator
- Pick a Quick Preset matching your asset type (hashed bundle, HTML page, CDN long + browser short, API, per-user, image), or build a header from scratch.
- Choose a Cacheability radio:
public(default for static assets),private(per-user),no-cache(must revalidate), orno-store(never store). - Toggle max-age and pick a value with a friendly unit (seconds/minutes/hours/days/years). The tool converts to seconds for the header. Add s-maxage if you want a different lifetime in CDNs vs browsers.
- For high-availability behaviour, enable stale-while-revalidate (serve stale while refetching) and stale-if-error (serve stale if origin is down).
- Tick any other directives you need (immutable, must-revalidate, no-transform).
- Copy from the Header Value banner, or pick a server-specific snippet
below (Nginx
add_header, ApacheHeader set, Expressres.setHeader, Cloudflare Page Rule, etc.).
Frequently Asked Questions
Should I use no-cache or no-store?
Despite the name, no-cache does not mean "don't cache". It means
"cache it, but always revalidate with the origin before reuse." If you really do not
want any cache to keep a copy at all (passwords, banking, one-time tokens), use no-store.
What's the difference between max-age and s-maxage?
max-age applies to every cache; s-maxage applies only to shared caches (CDNs, reverse proxies) and overrides max-age
there. The classic combo for CDN-backed sites is a long s-maxage (so the CDN holds it
for hours) plus a short max-age (so browsers re-check quickly when they navigate back).
When should I add immutable?
Add immutable only when the URL contains
a content hash or version, e.g. /static/app.7c3f2b.js. With max-age + immutable, browsers skip the
revalidation request even on a hard refresh, which is a big perf win. Never use it
with un-versioned URLs — you will not be able to push updates.
Does the HTML <meta> tag really work?
Mostly no. The <meta http-equiv="Cache-Control"> tag is widely ignored by modern browsers and almost always ignored by intermediate
caches and CDNs. The HTTP response header is the only reliable signal — only use the <meta> snippet as a last-resort
hint when you can't change server config.
What about Expires and Pragma?
Both are HTTP/1.0 holdovers superseded by Cache-Control. If you send Cache-Control, modern caches ignore Expires entirely. Pragma: no-cache is a request-only legacy
directive — sending it on responses does nothing useful.
Why does my CDN ignore my Cache-Control?
Common causes: a downstream rule (Cloudflare Page Rule, AWS CloudFront cache
behaviour) overrides origin headers; the request has cookies or Authorization, which makes most CDNs skip
caching; or the response is over the CDN's max object size. Check the CDN's "show
cache key" or cf-cache-status / x-cache debug header to see what
actually happened.
Is data sent to a server?
No. The generator runs entirely in your browser; everything you type stays on your device. There is no signup, no telemetry, and no upload.