Shaduf.Research preview

Field guide · updated 28 Oct 2026

HTTP Cache Field Guide

Choose cache headers that fit the response—and diagnose “old content” without accidentally sharing private data.

Decision order: who may store it → how long it may be fresh → how it should validate → which request variants must stay apart.

The short answer

Separate storage audience, freshness, stale permission, and matching. Use private, no-cache when a personalized response may stay in a browser but must not enter a shared cache; use no-store when compliant HTTP caches should not intentionally retain it. Add validators for cheap revalidation. When both conditional validators are sent, If-None-Match wins. A stale extension never grants storage or repairs a bad key. Request Cache-Control fields are different: they express advisory client preferences, not response policy or universal origin/purge commands.

New · 28 Oct 2026 · RFC 8246

What does immutable change for a versioned asset?

It says the representation will not change during its freshness lifetime. A fresh stored response should not be conditionally revalidated by default, including on reload; stale responses return to ordinary revalidation rules. max-age supplies the example lifetime, not immutable. A force reload can be an explicit override.

Standards and documentation review only: no browser, cache, endpoint, or provider was tested. MDN’s Chrome reload caveat is specific to subresources on reload and is not a universal browser claim. Open the concise guide · Read the dated report →

New · 22 Oct 2026 · 304 validation

Which stored response does a 304 update?

First build the request-compatible candidate set; stale entries are not excluded just for being stale. A strong validator selects all matching candidates. Without one, a matching weak validator selects only the most recent response; without any validator, only one validator-less candidate can qualify.

Standards-only, synthetic example: a 304 updates selected metadata, not replacement bytes. No cache implementation was tested. Open the practical guide · Read the dated report →

New · 19 Oct 2026 · authenticated requests

Does proxy-revalidate permit shared reuse of an Authorization response?

RFC 9111 §3.5 lists must-revalidate, public, and s-maxage as shared-cache permissions for responses to requests carrying Authorization. proxy-revalidate is not on that list; it governs validation before stale reuse. Erratum 9004 proposed a no-behavior-change clarification, but its final disposition was not confirmed from the accessible archive record.

Standards and archive review: no cache implementation behavior was tested. Read the dated report →

New · 13 Oct 2026 · missing versioned assets

A missing asset response can be reused—but is not necessarily cached

RFC 9110 makes 404 and 410 heuristically cacheable; HTTP does not require a cache to store them or specify a universal heuristic lifetime. If a cache stores a 404 for a versioned asset, restoring bytes at that same URI may remain hidden while the stored response is fresh. A new no-store response does not purge an older 404, and Age alone does not identify the responding hop.

Documentation-only: no endpoint, browser, provider, cache, or deployment was tested. Open the missing-asset guide · Read the dated report →

New dated follow-up · 7 Oct 2026 · request directives

A request can express a cache preference; it cannot command every cache

RFC 9111 calls request directives advisory: caches may honor them, but need not. Response directives have a different, mandatory role. Request no-cache is not guaranteed origin revalidation, max-age=0 is not a purge, and no-store does not delete an older entry. only-if-cached is a stored-response preference—not a universal no-forwarding guarantee.

Documentation-only: no authorized runtime or browser/provider experiment was available, so the examples are expected semantics, not live observations. Open the decision-first summary · Read the dated report →

New dated follow-up · 10 Oct 2026 · POST responses

A POST response may serve GET or HEAD—but only under narrow conditions

RFC 9110 requires explicit response freshness and a Content-Location equal to the POST target URI for POST-specific cache eligibility. That permission is for a later GET or HEAD, not another POST; it does not require a cache to store or reuse the response. Separately, an unsafe POST must be forwarded first; a 2xx/3xx response triggers target-URI invalidation only at caches the request traverses.

Expected-only: this is a standards review, not a live cache test. Open the POST response guide · Read the dated report →

New dated follow-up · 4 Oct 2026 · browser HTTP cache

Same resource URL, separate browser contexts

Browser HTTP-cache partitioning can make the same URL a separate local candidate under a different top-level site. It does not replace HTTP matching, Vary, freshness, or validation, and it does not configure a CDN or proxy. Use response policy—not partitioning—to control private or sensitive storage.

Documentation-only: examples are expected from standards and engine documentation, not tested. Open the reader summary · Read the dated report →

New dated follow-up · 1 Oct 2026 · HTTP redirects

A moved URL can keep an old redirect target

Each redirect response belongs to the URI requested at that hop. A cached response can retain an older Location; a later redirect in the chain is a separate cache candidate. A new policy does not erase older copies.

Documentation-only: no route, browser, provider, or cache was tested. Open the reader summary · Read the dated report →

New dated follow-up · 25 Sep 2026 · standards-grounded

When stale HTTP content is allowed

Ask four questions in order: was the response stored, which max-age or shared s-maxage applies, does a bounded stale permission apply, and can the entry validate? stale-while-revalidate and stale-if-error are support-dependent permissions. Under the portable RFC 9111 reading, do not treat them as overrides for no-cache, must-revalidate, proxy-revalidate, or shared s-maxage revalidation.

Documentation-only: all timing rows and header examples are expected, not live measurements. Open the reader summary · Read the dated report →

New · 28 Sep 2026 · service-worker update

A worker update does not replace an open page

A successful worker candidate can wait while old clients use the registration. Forced activation can change their controller without replacing their in-memory code. Cache Storage is script-managed and is not cleared by activation; retain old assets until the application compatibility rule allows cleanup.

Documentation-only: no app, browser, origin, or lifecycle test was supplied. Open the reader guide · Read the dated report →

New dated report · 23 Sep 2026 · provider-neutral

Deploy safely and diagnose old content

Use the new provider-neutral runbook for two paths: keep personalized or sensitive responses out of shared storage, or ship public and versioned content with explicit browser/shared freshness, validators, and named-hop evidence.

Documentation-only: no live provider capture was available. Open the runbook guide · Read the dated report →

Four decisions before shipping a cacheable response

DecisionQuestionUseful starting point
1 · AudiencePrivate or safely shared? Cookies and authentication can make the body user-specific.Decide the audience before adding public or s-maxage.
2 · LifetimeHow long is fresh?Set explicit max-age; shared caches may use a separate s-maxage.
3 · ValidationHow does stale content recover?With both validators, If-None-Match is evaluated before If-Modified-Since.
4 · VariantsWhat changes the body?Keep target URI, Vary-nominated fields, cookies, authorization, and unlisted application inputs from creating a privacy mismatch.
The cache decision path A request becomes a candidate through method and target URI, then passes Vary, privacy and freshness gates before a cache can reuse it or forward it. Requestmethod + URIheaders / cookies Candidate keyminimum: method +target URIextra material may vary GatesVary matches?private/shared allowed?fresh or validated?A match is not permission. Reuse / forwardhit → responsemiss → next hop
Read the evidence in order: a hit marker is meaningful only after the intended hop, key inputs, variant constraints, and storage policy are understood.

Pick a response class

Response classStarting policyGuardrail
Personalizedprivate, no-cacheA browser may retain a copy; a shared cache must not. Use no-store when intentional HTTP-cache retention is unacceptable.
Public dynamicpublic, max-age=60, s-maxage=10Only when the representation is safe to share and request variants are accounted for.
Versioned assetpublic, max-age=31536000, immutableFingerprint the URL and deploy a new URL for changed bytes.
Must not storeno-storeCompliant caches should not intentionally store or use it; it does not erase an older entry or encrypt the network.
New · 16 Sep 2026

Locate the serving layer

An old response may come from history/bfcache, a service worker/Cache API, the browser HTTP cache, an intermediary, or the origin. Start by asking whether a new fetch happened; then seek positive, named evidence rather than inferring from 200, a DevTools label, or a missing header.

Open the serving-layer diagnosis guide → · Read the dated report

New report · 20 Sep 2026 · Cloudflare-specific

Cloudflare Cache Rules and Origin Cache Control

Cloudflare adds product-specific controls around ordinary HTTP semantics: Origin Cache Control, the matching Cache Rule's Edge Cache TTL, Browser TTL, cache-key dimensions, and purge scope must be read separately.

Documentation-only: no zone, authorized response, or purge was available. Open the Cloudflare guide page · Read the dated report →

New · 25 Oct 2026 · RFC 9213

Can a CDN use a different cache lifetime?

RFC 9213 defines CDN-Cache-Control as a targeted policy, distinct from ordinary shared-cache s-maxage. A targeted cache selects the first valid non-empty field on its ordered list; its policy replaces ordinary Cache-Control/Expires for that cache. Cloudflare documents a proprietary field ahead of the standard CDN field, with product-specific forwarding and override rules.

Documentation-only: synthetic freshness example; no cache, zone, or endpoint was tested. Open the targeted cache-control guide · Read the dated report →

Audit refresh · 19 Sep 2026 · CloudFront-specific

CloudFront TTL policy and invalidation

For a named CloudFront behavior, inspect the effective minimum/default/maximum TTLs and cache key. A positive minimum can override origin no-store, private, or no-cache; the audit also narrows the standalone s-maxage documentation gap and keeps viewer headers separate from edge evidence.

Documentation-only: no distribution, cache capture, or invalidation was run. Open the CloudFront guide page · Read the audit refresh →

Use the cache freshness calculator

Need to compare a browser max-age with a shared-cache s-maxage? Open the Cache-Control freshness calculator → for the interactive inputs, formula, browser/CDN explanation, worked examples, FAQ, and limits.

It is a teaching calculation for supplied lifetime and age values—not a complete RFC 9111 current-age calculation, a security boundary, or a vendor configuration test. The original sandboxed tool remains at the existing tool URL.

To calculate current age from Date, Age, and timing instead of supplying an age, see the RFC 9111 Age/current_age guide and its synthetic worked example.

Search published pools, pages, reports, and evidence.