advanced25 min studyLesson 205 in Engineering

Freshness and validation answer different cache questions

Calculate response age, select the correct stored variant, and distinguish fresh reuse, conditional validation, storage prohibitions, and eviction.

On this page

What you’ll understand

  • Compare freshness lifetime against current age under explicit assumptions.
  • Explain ETag-based validation and a 304 response without treating it as content.
  • Distinguish freshness, storage permission, variant identity, and cache capacity.

A cache first needs the right stored response, then permission to reuse it, then evidence that reuse is fresh enough for the request. Finding a key in memory is only the first step. A validator can help ask the origin whether a selected representation has changed; a freshness lifetime can avoid that round trip for a while. Neither mechanism means the stored bytes stay current forever or that private data is automatically safe in a shared cache.

Age includes time before and after local storage

HTTP freshness compares a response's freshness lifetime with its current age. Explicit directives such as max-age establish a lifetime, while shared-cache directives can change the applicable choice. Current age includes corrected age when the cache received the response plus subsequent residence time; it is not simply time since this particular process inserted the entry. Date, Age, response timing, and transit contribute under the specification's age calculation. A response can already be old when a downstream cache sees it, so resetting its age to zero at every hop would improperly extend freshness.

A simplified exercise can supply corrected initial age directly, then add local residence to avoid pretending to implement all clock corrections. Freshness lifetime must be strictly greater than current age for ordinary fresh reuse; equality is not fresh. Request directives and response restrictions can still require validation, and stale-serving rules have explicit conditions. A cache must not turn 'stale' into 'always unusable' or 'always acceptable.' Record the policy under which reuse occurs, especially when availability behavior deliberately permits stale responses during a failure or a bounded background revalidation interval.

Acurrent=Ainitial,corrected+tresidence,fresh  ⟺  F>AcurrentA_{\rm current}=A_{\rm initial,corrected}+t_{\rm residence},\qquad \text{fresh}\iff F>A_{\rm current}
All ages and freshness lifetime F are seconds. This is the final age step after the RFC's initial-age corrections; fresh reuse additionally depends on request directives, matching the selected variant, and applicable cache restrictions.↔ Scroll wide equations horizontally.

A validator checks a selected representation

An entity tag identifies a representation version under the origin's validator rules. A cache can send If-None-Match for the selected stored response; an applicable 304 response lets it reuse the stored content with metadata updates rather than receiving a new body. A 304 is not a redirect and does not supply a replacement body. Strong and weak validators support different comparisons: a weak tag can support ordinary cache validation without promising byte-for-byte identity for uses that require a strong validator. Last-Modified offers another validator with its own precision and semantics.

Validation has to correspond to the correct representation variant. A tag associated with one language or encoding must not be blindly attached to unrelated stored content. On a changed representation, the origin can return new content and a new validator. On a failed revalidation, whether stale content may be served depends on applicable directives and conditions; a network error does not rewrite the representation as fresh. Keep the stored body, validator, selection metadata, and age state coherent when replacing or updating entries so a successful conditional exchange cannot accidentally authorize the wrong bytes.

Bsaved≈Bfull response−Bvalidation exchangeB_{\rm saved}\approx B_{\rm full\ response}-B_{\rm validation\ exchange}
Both terms are transferred bytes over the same accounting boundary in an illustrative comparison. A successful conditional validation can save body transfer, but still incurs request/response latency, metadata traffic, and origin work; no universal byte or time saving is guaranteed.↔ Scroll wide equations horizontally.

Storage policy and eviction are independent axes

Cache-Control: no-cache permits storage but requires successful validation before reuse under its rules; no-store instructs the cache not to store the affected response information. Private controls shared-cache storage rather than encrypting content or replacing authorization. Authorization and other shared-cache conditions need their own checks. Separately, a cache can evict an otherwise fresh response because it lacks capacity. Freshness answers whether eligible stored content is reusable; eviction answers whether the cache still has it. A hit-rate dashboard that ignores validation and origin traffic can overstate how much work the cache actually avoids.

The cache lab isolates capacity and recency without HTTP semantics. Reset, explicitly set BOTH capacity C=4 and stride s=4, predict twelve hits among the sixteen requests already processed at t=0, then Play or Step. Reset and re-set BOTH C=3 and s=4; predict zero hits at t=0 because the four-address cycle exceeds capacity. The displayed request count is N=min(4096,16+floor(2t)); parameter changes retain t and recompute from an empty cache. There are no TTLs, validators, variants, or authorization checks. Explain why a toy LRU hit is not evidence that an HTTP response is fresh or permitted for reuse.

A response arrives with inherited age

A stored response has max-age=60 seconds and corrected initial age 12 seconds when received. Ignore other directives and assume the selected variant matches. Compare reuse after 30 and 50 seconds of local residence.

  1. After 30 seconds, current age is 12+30=42 seconds. Since 60>42, the response is fresh under the simplified policy, with 18 seconds left before freshness expires.

  2. After 50 seconds, current age is 12+50=62 seconds. It is stale; resetting age to 50 would incorrectly forget inherited age.

  3. If a conditional request then obtains an applicable 304, use the stored body and update metadata and age according to the validation exchange. The 304 itself does not contain a new 60-second body or guarantee the old validator fits another variant.

The result

Freshness depends on total current age, while revalidation checks the selected representation and updates its reuse evidence.

Explore the model

Interactive lab

Interactive lab · cache

A capacity hit is not a freshness decision

For EACH run Reset, explicitly re-set BOTH C and s, predict, then Play or Step. At t=0, N=16 requests: (C,s)=(4,4) yields twelve hits; (3,4) yields zero. Playback uses N=min(4096,16+floor(2t)), and edits retain t/recompute from empty. This deterministic LRU cache has no freshness lifetime, validator, HTTP selection, or access policy.

A capacity hit is not a freshness decisionA fully associative LRU cache starts empty and requests address (i·s) mod 16. Hits move an address to the newest position; misses evict the oldest when full. Playback starts with 16 requests and adds two per second, capped at 4096 explicitly simulated requests. This toy stream is not a processor-cache benchmark. Current readings: Hits / requests: 0 / 16; Hit rate: 0%; Address-stream period: 16 addresses. All parameters are adjustable with the labeled controls below.Fully associative LRU cache after 16 deterministic requests: 0 hits and 16 misses.Most recent 16 requestsaddress = i × 3 mod 160M3M6M9M12M15M2M5M8M11M14M1M4M7M10M13MCurrent cache order · oldest → newest471013Latest address 13 · miss: inserted as newestToy address stream · period 16 · starts empty
Cached addressMiss / evictionMost recent request
Hits / requests
0 / 16
Hit rate
0%
Address-stream period
16 addresses
t = 0 s

A fully associative LRU cache starts empty and requests address (i·s) mod 16. Hits move an address to the newest position; misses evict the oldest when full. Playback starts with 16 requests and adds two per second, capped at 4096 explicitly simulated requests. This toy stream is not a processor-cache benchmark. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forCapacity determines whether bytes remain cached; HTTP freshness and authorization determine whether those bytes may be reused.

Check your understanding

Which interpretation of Cache-Control: no-cache is correct for a reusable stored response under its applicable rules?

Try it yourself

A response has freshness lifetime 90 seconds and corrected initial age 20 seconds. At local residence 70 seconds, is it fresh? What if residence is 69 seconds, assuming no other restrictions?

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Use total age and a strict greater-than comparison, not greater-than-or-equal.

Compare with the solution

At 70 seconds of residence the total age is 90 seconds, so the response is not fresh because 90 is not greater than 90. At 69 seconds total age is 89, leaving one second of freshness under the simplified assumptions. Matching, request directives, and reuse restrictions still apply.

Take it with you

  • Freshness uses total response age, including inherited and locally resident time.
  • Validators support conditional checks for the selected stored representation.
  • Storage permission, eviction, freshness, and shared-cache safety are separate decisions.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.