HTTP Cache Headers Generator — Free Online Cache-Control Builder
Generate correct Cache-Control headers for HTML, JS, images, fonts, and APIs. Configure max-age, stale-while-revalidate, immutable, and more. Get the header string + Nginx/Apache snippets.

HTTP Cache Headers Generator — Free Online Cache-Control Builder
If you've ever typed Cache-Control: into a server config and paused to wonder whether you wanted no-cache or no-store — or whether stale-while-revalidate goes before or after max-age — this tool is for you.
HTTP Cache Headers Generator builds the correct Cache-Control directive string for any resource type, explains every directive in plain English, and outputs ready-to-paste Nginx and Apache configuration snippets. 100% client-side, no signup required.
What Is a Cache-Control Header?
Cache-Control is an HTTP response header that tells browsers, CDNs, and proxy caches how long to store a response and under what conditions to revalidate it. A correctly set Cache-Control header can eliminate unnecessary network requests for returning visitors and significantly improve Core Web Vitals scores.
Getting it wrong has real consequences: too permissive and users see stale content; too restrictive and you burn server bandwidth re-serving the same files on every request.
How Do You Generate Correct Cache-Control Headers?
Generating a correct Cache-Control header takes three steps: choose a visibility (public, private, no-cache, or no-store), set a max-age appropriate for how often the resource changes, and add optional directives like stale-while-revalidate or immutable based on your caching strategy.
The challenge is that the right combination depends on the resource type. A JavaScript bundle with a content hash in its filename should use public, max-age=31536000, immutable. An HTML page should use public, max-age=0, must-revalidate or public, max-age=0, stale-while-revalidate=60. An API response for authenticated data should use private, max-age=0, must-revalidate.
The tool handles this with six presets:
- HTML Pages — zero
max-age,must-revalidate, optionalstale-while-revalidate - CSS / JS (hashed assets) — one-year
max-agewithimmutable - Images — 30-day
max-agewithstale-while-revalidate - Fonts — one-year
max-agewithimmutable - API Responses —
private, zeromax-age,must-revalidate - Custom — set every directive yourself
Each preset fills in sensible defaults. You can then override any individual directive before copying the output.
What Is the Difference Between no-cache and no-store?
no-cache does not mean "do not cache." It means "cache this response, but always check with the server before using it." The browser stores the response but sends a conditional request (If-None-Match or If-Modified-Since) to verify freshness before serving it. If the server responds with 304 Not Modified, the cached copy is used — no full download required.
no-store means "never store this response anywhere." The browser does not cache it at all and must make a full request every time. Use no-store for sensitive data: banking pages, session tokens, personal account information.
The confusion between no-cache and no-store is one of the most common HTTP caching mistakes. The tool's plain-English explanation panel describes exactly what your current configuration does as you configure it.
When Should You Use stale-while-revalidate?
stale-while-revalidate=N tells the browser it can serve a stale (expired) cached response immediately while fetching a fresh copy in the background. The user sees content instantly — no waiting for a network round-trip — and the fresh copy replaces the stale one for subsequent requests.
Use it when:
- The resource updates frequently but not instantly — news pages, dashboard data, API responses with short TTLs
- Perceived performance matters more than guaranteed freshness — most content sites fall into this category
- You accept a one-request lag before new content appears — users get stale content once; everyone after them gets the fresh version
The background revalidation window (the N value) controls how long the browser continues serving stale content. A stale-while-revalidate=60 on an HTML page with max-age=0 means: serve the cached page immediately, fetch a fresh copy, and stop serving stale content after 60 seconds if the fetch fails.
When Should You Use immutable?
Use immutable when you deploy assets with a content hash in the filename — for example, main.a1b2c3d4.js generated by Webpack, Vite, or esbuild. The immutable directive tells the browser that the file will never change during its max-age window, so it can skip the conditional revalidation check entirely on page reload.
Without immutable, browsers send a conditional request (If-None-Match) on every page reload even if the file hasn't changed, wasting a round-trip. With immutable, the browser serves the cached file unconditionally.
Never use immutable without a content hash in the filename. If the filename is static (bundle.js) but the content changes, users will serve a stale file until the cache expires — which could be up to a year.
What Is the Difference Between max-age and s-maxage?
max-age applies to all caches: both the user's browser and shared caches like CDNs and proxies. s-maxage overrides max-age specifically for shared caches while leaving browser behavior unchanged.
This is useful when you want your CDN to cache responses longer than browsers do. For example:
Cache-Control: public, max-age=60, s-maxage=86400
This tells browsers to cache the response for 60 seconds but allows a CDN to cache it for 24 hours. The CDN serves cached content for a full day; browsers revalidate every minute. You get CDN performance without stale browser caches.
How to Use the Tool
- Select a resource type — HTML, CSS/JS, images, fonts, API, or custom
- Adjust directives — toggle
immutable, setstale-while-revalidate, choose visibility - Copy the output — header value, full header line, or Nginx/Apache config snippet
The output updates in real time as you change settings. The plain-English explanation panel describes every active directive so you understand what your configuration actually does before deploying it.
Cache-Control Quick Reference
| Resource Type | Recommended Header |
|---|---|
| HTML page | public, max-age=0, must-revalidate |
| HTML with SWR | public, max-age=0, stale-while-revalidate=60 |
| Hashed JS/CSS | public, max-age=31536000, immutable |
| Unhashed JS/CSS | public, max-age=86400 |
| Images | public, max-age=2592000 |
| Web fonts | public, max-age=31536000, immutable |
| Private API | private, max-age=0, must-revalidate |
| Public API | public, max-age=60, stale-while-revalidate=30 |
| Sensitive data | no-store |
Try the tool: http-cache-headers-generator.tools.jagodana.com


