Prompt
My CDN is serving stale files after deploys, how do I fix cache purging?
Latest observation
Stale CDN content after deploy usually comes from one of a few issues: the CDN cache wasn’t actually invalidated, the origin is still serving cacheable headers, or the app is using filenames/URLs that don’t change between deploys.
Best fix: use cache-busting asset URLs
Instead of purging every deploy, make static assets immutable and change the URL whenever the content changes.
Examples:
app.css→app.8f3a1c.cssmain.js→main.a91c2d.js- or add a version query string, though filename hashing is usually better
Then set headers like:
Cache-Control: public, max-age=31536000, immutablefor hashed assetsCache-Control: no-cacheor a short TTL for HTML and config files
This is the most reliable approach because the CDN doesn’t need to guess what changed.
If you want to purge on deploy
Make sure the purge targets the exact URLs the CDN cached.
1) Purge the right paths
Common mistake: purging /static/* when the CDN cached:
/app.js/assets/app.1234.js/index.html
Use:
- exact URLs, or
- wildcard purge if your CDN supports it
Examples:
- purge
/index.html - purge
/assets/* - purge by cache tag, if supported
2) Purge after the new files are uploaded
If you purge first, the CDN may re-cache old files from origin before the deploy finishes.
Recommended order:
- Upload new build artifacts
- Verify origin serves the new version
- Purge CDN cache
- Confirm the CDN fetches the new content
3) Check origin cache headers
If your origin sends long cache headers on HTML, the CDN may keep serving stale pages even after deploy.
For HTML:
Cache-Control: no-cache, must-revalidateorCache-Control: max-age=0, s-maxage=60depending on your setup
For hashed assets:
- long-lived caching is fine
4) Verify the purge actually succeeded
Most CDNs return a purge request success response, but you should still verify:
- check CDN response headers like
Age,X-Cache,CF-Cache-Status,X-Served-By - confirm the content hash or build ID changed
- request the asset with a cache-bypass header or query param if your CDN allows it
Common causes of stale content
- HTML cached too long at the CDN
- Same asset filenames across deploys
- Service worker serving old assets
- Browser cache, not CDN cache
- Purging the wrong hostname or environment
- Origin
ETag/Last-Modifiedcausing unexpected revalidation behavior - Multiple CDN layers or a reverse proxy in front of the CDN
Recommended deploy pattern
- Build assets with content hashes
- Set HTML to short/no cache
- Set hashed assets to immutable long cache
- Deploy new assets
- Deploy new HTML last
- Optionally purge only HTML
That usually eliminates the need for broad CDN purges.
Quick diagnostic checklist
- Does the asset URL change when content changes?
- Are you purging the exact CDN hostname and path?
- Is HTML cached too aggressively?
- Are you purging after upload?
- Is there a service worker involved?
- Are browser DevTools showing
from disk cacheinstead of CDN?
If you tell me which CDN you use (Cloudflare, Fastly, Akamai, CloudFront, etc.) and how you deploy assets, I can give you the exact purge configuration and headers to use.