Lesson 03 · Advanced frontend rendering

Cache is a correctness policy

Estimated time: about 14 minutes

Caching decides which past representation may stand in for the present, for which audience, and for how long. Performance is the consequence; correctness is the design.

14 minLifecycle + architecture drill

Every cache needs four answers

1 · Value

Exactly which representation is stored: HTML, RSC payload, API response, query result, or asset?

2 · Key

Which inputs distinguish entries: URL, locale, region, device, authorization, experiment, or tenant?

3 · Lifetime

How long may the value be reused without checking its source?

4 · Exit

What expires, validates, invalidates, refreshes, or safely serves stale data?

correct cache = correct value × complete key × accepted staleness × reliable invalidation

A page is cached more than once

Framework discussions often say “the cache” while several independent stores are active. Each has its own key, lifetime, and purge mechanism.

Browser

Private HTTP cache

One user agent. Can safely retain some personalized responses when marked private. History and client-router caches have separate semantics.

Network

Shared CDN cache

One entry can serve many users. Excellent leverage—and the most dangerous place to omit tenant, locale, or personalization from the key.

Application

Render/output cache

Stores generated HTML or framework payloads. ISR and prerender caches live here, sometimes coordinated across instances.

Data

Query/object cache

Stores fetches, database results, or computed objects. A fresh page render can still consume stale data from this layer.

Stale-while-revalidate, request by request

This simulation uses a 60-second fresh lifetime plus an allowed stale window. Notice that regeneration is usually triggered by traffic, and that the request crossing the boundary may still receive the old representation.

t = 0s
Walk through one cache entry.

Browser

Requests /article

Shared cache

Empty

miss
Origin

Generates version 1

MISS — version 1 is returned and cached for 60 seconds.

Use the verbs precisely

Store

Retain a response. Storage does not imply it can be reused without a check.

Reuse while fresh

Serve without contacting the origin because age remains within the declared lifetime.

Validate

Ask whether a stored representation is still current, commonly with an ETag or Last-Modified conditional request.

Invalidate

Mark or remove entries after a known change. This must reach every layer that can still answer independently.

The naming trap: HTTP no-cache permits storage but requires validation before reuse. no-store asks caches not to store the response. private permits a private cache but excludes shared caches.

What can go wrong

FailureMechanismSenior response
Data leakPersonalized output stored under a shared keyMake it private or remove personalization; audit every key dimension.
Stale correctnessDisplay cache treated as transactional truthRevalidate price, permissions, and inventory during the mutation.
Split-brain cacheOne instance or layer receives invalidation; another does notUse shared tag state, purge CDN variants, and observe propagation.
Cache stampedeMany misses regenerate the same expensive entryCoalesce requests, jitter expiry, refresh early, or serve bounded stale data.
Key explosionHigh-cardinality cookies or headers fragment shared entriesNormalize intentional variants; avoid broad Vary dimensions.
Permanent staleInvalidation event is lost and TTL is effectively infiniteCombine event invalidation with a bounded backstop expiry.

What ISR really buys

Incremental Static Regeneration reuses prerendered output and regenerates it after time or an explicit event. It is a useful implementation of cached rendering—not a guarantee of immediate freshness.

Good fit

Large public page sets, expensive rendering, high cache reuse, and bounded staleness that the product accepts.

Poor fit

User-specific output, strict read-after-write expectations, authorization decisions, or values that must be current for a transaction.

Time revalidation

Simple backstop, but refresh happens whether or not content changed and may begin only after later traffic arrives.

Event revalidation

Precise when reliable, but requires dependency tags, delivery guarantees, and coordination with outer CDN caches.

Architecture drill

Scenario: Product copy changes hourly. Regional prices change each minute. Signed-in customers can receive private discounts. Stock may be approximate on the page, but an order must never confirm unavailable inventory. What policy should lead your answer?

A senior-shaped interview answer

“I would cache by data class rather than choose one policy for the route. Product copy is public and stable, so I’d cache it broadly and invalidate by product tag. Regional price needs a normalized region key and a much shorter freshness budget.”

“Account discounts must not enter a shared representation. I’d render or fetch them through a private boundary. Stock on the page can be a bounded-stale signal, but checkout must atomically re-check or reserve inventory—the display cache is never the authority.”

“I’d verify cache keys, Age and Cache-Status headers, hit ratio, regeneration latency, purge propagation, stale-serving counts, and origin load. In a multi-instance deployment, tag invalidation and any upstream CDN purge need explicit coordination.”

Primary reading