Home
/
Apps
/
HTTP Cache-Control Header Calculator
HTTP Cache-Control Header Calculator

HTTP Cache-Control Header Calculator

Build a valid HTTP Cache-Control header from max-age, s-maxage and revalidation options, and see a plain-English explanation of what each directive does.

Build a valid HTTP Cache-Control header from max-age, s-maxage and revalidation options, and see a plain-English explanation of what each directive does.

How long the response stays fresh. Use 0 to omit.

Overrides Max-Age for shared caches like CDNs. Use 0 to omit. Only applies to Public.

Extra time a stale copy may be served while a fresh one is fetched in the background. Use 0 to omit.

Extra time a stale copy may be served if the origin server errors. Use 0 to omit.

Share this app

HTTP Cache-Control Header Calculator

The Cache-Control HTTP header tells browsers, proxies, and CDNs how - and for how long - a response may be cached. Getting it wrong is one of the most common causes of stale content being served to users, or of servers being hammered with requests that should have been served from cache. This tool builds a syntactically correct Cache-Control header from a handful of plain options and explains what each directive actually does.

What is Cache-Control?

Cache-Control is a response header defined by RFC 9111 (the HTTP Caching specification). A typical value looks like:

Cache-Control: public, max-age=3600, s-maxage=600, stale-while-revalidate=86400

Each comma-separated part is a directive. Some directives take a numeric argument (like max-age=3600), others are standalone flags (like must-revalidate).

The directives this calculator covers

  • Cacheability - exactly one of:
    • public - any cache (browser, proxy, CDN) may store the response, even if it would normally be considered private (e.g. it had an Authorization header).
    • private - only the end user's browser may cache it; shared caches like CDNs must not.
    • no-cache - caches may store the response, but must revalidate with the origin server on every use before serving it.
    • no-store - nothing may be cached at all; every request goes to the origin.
  • max-age=<seconds> - how long the response is considered fresh from the moment it was generated.
  • s-maxage=<seconds> - like max-age, but only applies to shared caches (CDNs, reverse proxies); overrides max-age for them. Ignored by browsers.
  • stale-while-revalidate=<seconds> - after freshness expires, the cache may keep serving the stale copy for this many extra seconds while it fetches a fresh one in the background.
  • stale-if-error=<seconds> - if the origin server errors while revalidating, the cache may serve the stale copy for this many extra seconds instead of showing an error.
  • must-revalidate - once the response is stale, it must not be served again without successful revalidation - overrides stale-while-revalidate/stale-if-error for that cache.
  • immutable - tells the browser the response body will never change while it's fresh, so it can skip revalidation entirely even on a user-triggered reload.
  • no-transform - forbids intermediate proxies from modifying the response body (e.g. re-compressing images or minifying text).

How this calculator works

freshness lifetime (browser)=s-maxage present?    max-age  :  max-age\text{freshness lifetime (browser)} = \text{s-maxage present?} \;\to\; \text{max-age} \; : \; \text{max-age}

For a shared cache such as a CDN, s-maxage (when present) always takes priority over max-age; browsers ignore s-maxage entirely and only ever look at max-age. The calculator builds the header string directive-by-directive in the canonical order (cacheability type first, then the numeric freshness directives, then the boolean flags), skips any directive left at zero/off, and shows the resulting duration broken down into seconds, minutes, hours, and days so it's easy to sanity-check.

Worked example

Suppose you're serving a versioned static asset (like app.a1b2c3.js) that never changes once published, through a CDN:

  • Cache type: public
  • Max-Age: 31536000 (1 year)
  • s-maxage: 0 (not needed - CDN can just follow max-age)
  • Immutable: Yes

This produces:

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

Browsers will cache this asset for a full year and never re-check it - exactly right for a filename that changes every time the content does.

For an API response that should be fresh for 30 seconds but can tolerate serving slightly stale data for up to 5 minutes while it refreshes in the background, you'd instead use:

  • Cache type: private
  • Max-Age: 30
  • Stale-While-Revalidate: 300
Cache-Control: private, max-age=30, stale-while-revalidate=300

How to use this tool

  1. Choose the cacheability type (public, private, no-cache, or no-store).
  2. Enter Max-Age in seconds (leave at 0 to omit it).
  3. Optionally set s-maxage, stale-while-revalidate, and stale-if-error for finer CDN/edge-cache control.
  4. Toggle must-revalidate, immutable, and no-transform as needed.
  5. Copy the generated header value straight into your server, reverse proxy, or CDN configuration.