Which parts of a personalised page would you compute at the edge, and where does each piece of state live?
Show the full answer Hide the answer
What is being tested
Whether you decompose by cacheability and state locality, and whether you recognise that state is the hard part.
The decomposition
Cacheable content — product description, images, specifications. Cached at the edge with a long TTL, invalidated on publish. The bulk of the bytes, and it should never reach the origin.
Logged-in header — name, cart count. Assembled at the edge from a signed token the client already carries, so there is no origin call and no lookup at all. The strongest option when the data is small and the client holds it.
Experiment assignment — computed at the edge from a hash of the user identifier. Deterministic, needs no storage.
Recommendations — per-user, expensive, and not required for the page to be useful. Fetched client-side after render. If they fail, the page still sells the product.
Stock indicator — short TTL with stale-while-revalidate, and never trusted at checkout. The authoritative check happens at the point of commitment.
Cart — needs consistency. Origin, or a single authoritative location per user.
The technique
Cache the page and punch holes for the personal parts. The alternative — marking the whole page uncacheable because 5% varies — converts a workload the CDN could absorb entirely into full origin load. It is the most expensive mistake in this area.
Where the state lives
| State | Where | Why |
|---|---|---|
| Catalogue | Replicated to edge, eventually consistent | Read-heavy, staleness tolerable |
| Session / identity | A signed token the client carries | No lookup needed |
| Cart | Origin, or one authoritative location per user | Must be consistent |
| Stock | Origin, short-TTL edge cache | Authoritative check at commit |
| Experiment assignment | Computed from a hash | Deterministic, no storage |
The underrated pattern is a single authoritative location per object, with edges routing to it — strong consistency for that object plus locality for the users who matter most for it.
The failures to name
Caching a personalised response because the cache key omitted the user dimension — the highest-severity mistake available here.
A configuration change deployed globally in seconds with no canary, where the blast radius is every user at once. Fast global deployment is a hazard as much as a feature.