Shaduf.
HTTP Cache Field Guide/Cache-Control calculator

Tool · cache freshness

Cache-Control freshness calculator

Calculate the illustrative freshness remaining for a browser or shared cache from a lifetime and a current age, all in seconds.

Use the controls first; then read the formula, browser/CDN distinction, worked examples, and limits below.

Try the calculator

Enter a browser max-age, a current age, and optionally a separate shared-cache s-maxage. The policy picker is a compact starting-point prompt, not a complete header generator.

The isolated tool is also available at the underlying calculator URL; the surrounding explanation is the indexable document.

The simplified freshness formula

remaining = max(0, freshness lifetime - current age)

A positive result is fresh. When age equals the lifetime, the result is stale, not fresh; the reported remaining freshness is zero. An age beyond the lifetime is also stale and stays clamped at zero.

Freshness timeline for a 60 second lifetime and 15 second age The fresh interval runs from zero to 60 seconds. At age 15 seconds, 45 seconds of freshness remain. After 60 seconds the response is stale. 45s remaining fresh interval stale 0s age 15s lifetime 60s older Illustration: max(0, 60 − 15) = 45 seconds
Freshness is a boundary, not a promise of storage. The timeline shows only the supplied lifetime and age; a cache may still choose not to store or reuse a response.

What the inputs mean

Browser / private cache

max-age gives a general freshness lifetime in seconds. In this teaching model, the browser result compares that lifetime with the supplied current age.

A private browser cache is different from a shared CDN or reverse proxy: a response can be suitable for one user’s browser without being safe to reuse for another user.

Shared cache / CDN

s-maxage, when present, supplies a separate freshness lifetime for shared caches. It lets a safe shared response have a different lifetime from the browser’s max-age.

Age is a response-header signal from a cache path. The widget uses one entered age for comparison, but different hops can have different ages and a missing Age header does not prove that the origin was contacted.

Important: s-maxage does not make a personalized representation safe to share, and max-age or s-maxage does not require a cache to store a response. Storage permission, cache-key matching, validators, and deployment configuration remain separate questions.

Worked examples

InputsCalculationResult
Lifetime 60s · age 15smax(0, 60 − 15)45s remaining; fresh
Lifetime 60s · age 60smax(0, 60 − 60)0s; stale — equality is the boundary
Lifetime 60s · age 75smax(0, 60 − 75)0s; stale — the result is clamped
Browser 60s · shared 30s · age 45smax(0, 60 − 45) and max(0, 30 − 45)Browser: 15s remaining; shared: stale

Do not mix freshness with storage policy

The calculator’s policy picker preserves the useful high-level distinction, but its suggested header is only a simplified starting point:

  • no-cache does not mean “do not store.” It permits retention but requires validation before ordinary reuse.
  • no-store tells compliant HTTP caches not to intentionally store or use the response. It does not erase an older entry, encrypt the network, or control every other application cache.
  • private limits a response to private caches; it is not a complete confidentiality guarantee.
  • Validators such as ETag and Last-Modified help a stale entry revalidate; they do not turn a stale response into a fresh one without a successful validation path.

For real policy, also account for response status, request variants, Vary, cookies, authentication, service workers, browser history, stale extensions, and provider-specific overrides.

Scope and limits

This is a teaching tool for the lifetime and current-age values you supply. It is not a complete RFC 9111 current-age calculation, and it does not test a real origin, browser, CDN, or reverse proxy.

The simplified model omits response/request timing, the Date field, resident time, clock skew, revalidation, stale-while-revalidate or stale-if-error, cache partitioning, history/bfcache, service workers, hidden cache-key inputs, and vendor defaults. The widget’s policy picker also does not model every directive or deployment rule. Treat its output as an explanation aid, then inspect the actual responding layer.

FAQ

Is a response fresh when age equals its lifetime?

No. In this simplified boundary check, equality is stale: max(0, lifetime − age) returns zero, and the calculator labels it stale.

Should I use max-age or s-maxage for a CDN?

Use max-age for the general/browser lifetime and add s-maxage when a safe shared-cache lifetime should differ. A shared cache still needs a safe representation, appropriate key/variant rules, and its own configuration.

Does the Age header always equal the current age?

No. The tool accepts a supplied age as a teaching input. A real RFC 9111 current-age calculation uses timing and metadata from the response path; Age is one signal, usually associated with shared-cache handling.

Does no-cache prevent a cache from storing a response?

No. no-cache requires validation before reuse. Use no-store when compliant HTTP caches should not intentionally retain the response; neither directive is a universal security boundary for every layer.

Does a stale result prove that a real server will return stale content?

No. It only describes the numbers entered here. Real behavior depends on storage, revalidation, stale permissions, cache layers, and provider configuration.

Read next

Search published pools, pages, reports, and evidence.