Why this exists

A cached page and a published page can quietly disagree with each other. The edit is live at the origin, but visitors keep getting served the version from before it, right up until something forces a refresh. Manually clearing that cache after every change works fine as a process - until the one time it's forgotten, and there's no way to tell from the outside whether that's happening on any given day.

What it actually looked like

A content change would go live at the source, but the cached version at the edge could keep serving the old copy until it either expired on its own or someone logged in and purged it by hand. That worked, but it depended entirely on remembering an extra step after every single edit - a step with no reminder, no confirmation, and no consequence visible until a visitor reported seeing something that was supposedly already fixed.

A related but separate problem sat on top of it: stylesheets and scripts kept the same filename across edits. A browser that had already cached one of those files under its old name had no reason to ask for a new copy, even after the file's contents changed on the server. That part couldn't be fixed by purging anything - a browser's own cache isn't something a server can reach into directly.

What was actually happening

These are two different caching layers with two different rules. Content pages are cached at the delivery network's edge, and that cache can be cleared on command. Static assets like scripts and stylesheets are cached inside each visitor's browser, tied to the exact URL requested - and a browser has no way of knowing a file changed unless the URL itself changes.

Treating both as the same problem was the mistake. Edge cache needed a purge triggered at the right moment. Browser cache needed a naming convention that changed automatically whenever a file's contents did, so the browser would treat it as a different file entirely rather than reusing what it already had.

The decision log

Decision 1: Trigger the purge from the deploy step itself, not a person

A step that runs automatically every time a change ships removes the "did I remember" variable entirely. It doesn't require discipline, and it doesn't degrade the tenth time it runs the way a manual habit can.

Decision 2: Scope the purge to content files only, not everything

Clearing the entire cache on every single push - including changes that have nothing to do with published content - would force the origin to be hit far more often than necessary, working against the reason a cache exists in the first place. The purge step filters by file type, and only fires for the ones that actually affect what a visitor sees.

Decision 3: Verify the purge happened, don't just trust that it ran

A deploy step reporting success and a cache actually being cleared are two different claims. Confirmation came from the delivery network's own activity log, showing the purge requests landing and attributing them to the automated step - not from assuming a green checkmark meant the job was done.

Decision 4: Solve the browser-cache problem with a name change, not a purge

There's no remote command that clears a visitor's own browser cache. Instead, each stylesheet and script's filename now includes a short hash generated from its contents. Change the file, and the hash changes with it, so the browser requests it as a brand-new file rather than reusing what it already had cached. A small script recalculates that hash automatically any time a source file changes, so nobody has to remember to update it by hand.

Before and after

Before

  • Cache purge depended on someone remembering to do it
  • Occasional stale content served for hours after a real edit
  • Script and stylesheet filenames stayed constant across edits
  • No confirmation the purge happened, only whether the deploy step reported success

After

  • Purge fires automatically on every relevant push, scoped to content file types
  • Confirmed against the delivery network's own activity log
  • Every stylesheet and script carries a version hash that changes with its contents
  • Publishing a change and clearing the cache are now the same action

What this actually took

A short automated step tied to the existing deploy process, and a small local script that recalculates version hashes for changed files. No new service to run, and no ongoing manual task once it was wired up - the only future work is extending the file-type filter if a new kind of asset needs the same treatment. Deploy hardening like this sits inside the Web & Digital practice.

Frequently asked questions

Why not just set a short cache expiration instead of purging manually?

A shorter cache lifetime limits how stale content can get, but it also throws away most of the performance benefit caching exists for - the origin gets hit far more often by every visitor, not just the ones arriving right after a change. Purging on demand, only when content actually changes, keeps a long cache lifetime for everything else.

Why version the filename instead of telling browsers not to cache the file at all?

Telling a browser never to cache a script or stylesheet means every visitor downloads it fresh on every visit, which defeats the purpose. A version hash in the filename gets both: aggressive caching until the file changes, and immediate pickup of the new version the moment it does.

How do you know the purge is actually working and not just reporting success?

By checking the delivery network's own log for purge requests attributed to the automated step, rather than only trusting the deploy tool's own success message. Those are two different claims, and only one of them confirms the cache was actually cleared.

Wondering if your site is quietly serving visitors a stale version of itself?

It usually shows up as "I already fixed that" for a change that technically shipped hours ago.