Conrad caching

Request path and caching

How a request reaches a Conrad storefront page and becomes interactive, and the cache layers along the way — browser, Cloudflare CDN, Valkey with stale-while-revalidate, Apigee and Nitro's cache — with the headers that control them and what happens to cached HTML during deploys.

From your Conrad Caching note and the request path in Conrad DevOps.

Know

  • The path: Cloudflare (bot checks, WAF) → Google load balancer → GKE → a Nuxt pod → Valkey for cached HTML → render on miss or stale → HTML back through Cloudflare → assets from the CDN → hydration.
  • Cache layers and lifetimes: browser (hashed JavaScript and CSS for a year, HTML revalidated every time, API responses 30 to 60 minutes), Cloudflare (static assets a year, product images long), Valkey (rendered HTML for 60 seconds with stale-while-revalidate, translations and other content), Apigee (ResponseCache for backend APIs).
  • Headers: public, max-age=31536000, immutable for hashed files; no-cache plus an ETag for HTML; s-maxage or CDN-Cache-Control to give the CDN a different lifetime from the browser.
  • Nitro: defineCachedEventHandler, defineCachedFunction (an alias of cachedFunction) and route-rule cache; options base, maxAge, swr, varies, getKey, integrity. In Nitro 2 the default storage is memory per pod, and swr defaults to true.
  • Deploys: cached HTML and open tabs reference the previous build's chunks, so old assets must stay available.
  • Consent and A/B on cached pages: consent only changes which scripts load, so it stays out of the cache and is handled in the browser after accept; an A/B variant changes the HTML, so it goes from the cookie into a header in middleware and into the cache key, like device type or tax mode.
  • Invalidation: the browser revalidates HTML every time, the server entry expires with maxAge or is deleted by key, the CDN is purged by URL or tag; say the staleness window out loud.

Fact check of your notes

Gotcha· HTML passes through Cloudflare, it is not stored there

The DevOps note says "Redis sends it to the CDN, which serves it to the user", while the same note says HTML is not cached at the CDN. Both fit if you read the first as "the response travels back through Cloudflare's proxy": the HTML cache is Valkey at the origin, and Cloudflare only forwards the HTML.

Gotcha· Names to get right in the room

"SWL" is stale-while-revalidate (SWR). "Vakley" is Valkey. "getKez" is getKey. Your note is right that without base the cache goes to the pod's memory.

Exercise

Exercise
  • Draw the request path from memory, with every cache layer and its lifetime, in under two minutes.
  • In a local Nuxt app, run Valkey with Docker Compose, mount it in a server plugin and add the route rule from the coding question; check with redis-cli keys '*' that HTML lands there and that a stale entry is served while it re-renders.
  • Write down your answer to "how is the HTML cache invalidated when a price changes?" and turn it into a question for them.

Be able to say

Be able to say· Walk us through a request to a Conrad product page.

"It hits Cloudflare first, for bot checks and the WAF, then Google's load balancer, then the GKE cluster, which routes it to a Nuxt pod. The pod checks Valkey for rendered HTML for this variant. Fresh, it returns it; stale, it still returns it and re-renders in the background; missing, it renders and stores it. The HTML goes back through Cloudflare without being cached there. The browser loads the hashed assets from the CDN and hydrates the page, and from then on navigation happens in the browser."

Be able to say· What are the cache layers, and why is HTML handled differently from assets?

"Hashed JavaScript and CSS are immutable, so the browser and the CDN keep them for a year. HTML has one URL but many variants, by device, language, login and B2B or B2C, and it must point at the current build, so the browser always revalidates it and it is cached at the origin, in Valkey, for 60 seconds with stale-while-revalidate. API responses are cached briefly in the browser and can be cached by Apigee. In Nitro, the cache lives in pod memory unless you mount shared storage, which is why Valkey matters with many pods."

Your notes

Open in Notes

Nothing yet. Notes filed here show up on this page and the section overview.