Project Hub
More
Alerts are account-scoped
Alert rules, channels and delivery history belong to your stack. Sign in with GitHub to configure them — nothing is fillable or clickable until then.
The edge cache is your friend... until it serves yesterday's build
Three times this week, I shipped a fix, verified it in production, and watched it not exist. The deploy went green. The URL served the old code. And the strangest part: it happened to a project about monitoring infrastructure.
This is a post about the caching layer nobody configures but everybody suffers from — the CDN edge — and the 5-minute checklist that now lives in my head before I trust any deploy. The bug stories are real and mine; the checklist is yours.
The lie: max-age=0, must-revalidate
My first mistake was assuming the response header alone decides caching. It does not. I served my HTML with Cache-Control: public, max-age=0, must-revalidate — which, in a sane world, means "may store, but revalidate before every use." The CDN, however, had different ideas: the edge kept answering requests with cf-cache-status: HIT and a build of the page from hours ago.
The lesson generalizes to every layer of the modern stack: your server's configuration is a suggestion; what actually serves your users is whatever the intermediary last decided to keep. A header is a request, not a command. The edge can — and sometimes does — hold on anyway.
How the lie got exposed (the 5-minute checklist)
1. Look at the cache header, not your code. curl -I your own URL and find cf-cache-status. HIT means the edge is answering without asking your server. This single line has saved me hours of reading my own diff in confusion.
2. Bust the cache with a query param. /your-page?v=1 is a different cache key to almost every CDN. If ?v=1 shows your new code while ? shows the old, you have your answer: it was never your deploy. It was the edge.
3. Only then touch cache rules. If the edge still serves stale content for new keys, your zone is caching aggressively and you need a page rule or a purge. Purging is a bandage; the rule is the cure. But do steps 1-2 first — I have watched people (me) purge a whole zone and celebrate before realizing the real problem was a hardcoded value in their HTML.
The second lie: the browser you can't control
Here is the uncomfortable part: even with the edge fixed, a user can open your app and see stale state — not from a CDN, but from their own localStorage or an old service worker. I spent an afternoon debugging "the fix didn't deploy" that had, in fact, deployed. My mistake was testing in a browser whose storage was full of yesterday's data. The fix that generalizes: when something "didn't change," try it in an incognito window before you touch anything else. It is free, it takes ten seconds, and it splits the problem space in half: mine vs. everyone's.
The honest defaults principle
One more thing the cache incident taught me, and it goes beyond caching: my HTML had demo numbers hardcoded as defaults ($1,890 MRR, "21/21 alive"). For weeks, whenever the app's JavaScript failed to boot, visitors saw these beautiful, confident, entirely fictional numbers. The HTML showed them because HTML always shows what it contains — and nothing else would overwrite it.
The fix was not better caching. It was honest defaults: empty stat cards that say $0 and "—" until real data arrives. Because the failure mode of any dynamic app is not "app broken." It is "app missing, placeholder lying." Every default value you ship is a promise about what your page says when everything else fails. Make it boring. Make it true.
Steal this checklist
Before trusting any deploy, in order, five minutes:
1. curl -I the URL → check cf-cache-status (or your CDN's equivalent).
2. Fetch with a cache-busting query param → if it differs, it is the edge, not you.
3. Open in incognito → if it differs, it is local storage or a service worker, not the deploy.
4. Check your HTML defaults → if the JS can fail, what does the page say? Is it a lie?
5. Only then look at cache rules and purges → and only if steps 1-3 came back clean.
The edge is not your enemy. It is just faster than your mental model of what "shipped" means. Every deploy is not a state change until the state has changed — and proving that takes a header, a query param, and a browser you don't usually use.