Short write‑ups of problems we hit running a real commerce operation and what we changed in the code because of them. No product announcements; just the reasoning.
For as long as the storefront has rendered on the server, a page missing from the cache cost about a second, and we kept blaming the size of the page. It was a translation helper. Every translated word left a small reactive effect behind in the rendering process, nothing ever cleaned it up, and every page drawn in a different language re-ran all of them. How a cost that grew with uptime gave it away, a heap diff full of translation keys, the twenty-line fix, and what changed once a cache miss cost 36 ms instead of 1.2 s.
After a flush, the first visitor to each storefront page pays for the render. We have written the thing that pre‑pays three times: a link‑following crawler from a package, a two‑pass seeder‑then‑deep crawl with concurrency rules, and — the one we kept — a list of the pages people actually visit, fetched in order of traffic, at a concurrency that can never outbid a live shopper. Why each version was wrong for the next stage, and the surge‑protection bug that made the warmer most aggressive exactly when it should have been gentlest.
Our storefronts are server-rendered and personalised, which is the worst case for an HTTP cache. Here is how we put Varnish in front of them anyway — two hash buckets, a logged-in bit, tagged objects, surgical bans, and a warmer that only warms what people actually visit.