Clear Hugo Cache & Fix Stale Content After Deploy
When old posts, images, or CSS linger after deploy — hugo --gc, resource cache, and CDN purge checklist.
Tested on: Hugo 0.139.4, Cloudflare CDN, local Windows + Linux CI Symptom: Deleted post still live. Updated CSS fingerprint unchanged. Images from 2024 build.
Hugo has three caches
resources/processed asset cache (inpublic/hashes):cacheDir(modules, images) — default OS temp- CDN/browser cache at edge
You must clear the right layer.
Layer 1: garbage collect on build
Always CI with:
hugo --gc --minify
--gc removes unused cached files from resources/ output.
Without it, orphaned hashed files accumulate — not user-visible but wastes storage.
Layer 2: blow away local cacheDir
hugo config | grep cacheDir
# C:\Users\me\AppData\Local\hugo_cache\ (Windows)
# /home/runner/.cache/hugo_cache/ (GitHub Actions)
Nuclear local reset:
rm -rf public resources
hugo --gc --minify
On CI, cache the dir between builds for speed OR delete for reproducibility:
# .github/workflows/deploy.yml
- name: Clear Hugo cache
run: rm -rf ~/.cache/hugo_cache
Layer 3: fingerprint assets
If CSS filename doesn't change after edit, you weren't fingerprinting.
{{ $css := resources.Get "css/extended/foo.css" | minify | fingerprint }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}" integrity="{{ $css.Data.Integrity }}">
Theme updates without fingerprint = browsers serve old stylesheet.css.
Deleted content still on CDN
Cloudflare cached /blog/deleted-post/ for 1 hour.
Purge:
# API or dashboard: Purge Everything (last resort)
# Better: purge by URL list
Set shorter HTML cache in _headers:
/blog/*
Cache-Control: public, max-age=600, must-revalidate
Error: resource not found in cache
error: resource "images/foo.jpg" not found in cache
Corrupt cacheDir. Delete cache dir, rebuild.
hugo.toml cache config
[caches]
[caches.assets]
dir = ":cacheDir/assets"
maxAge = "720h"
[caches.images]
dir = ":cacheDir/images"
maxAge = "720h"
Lower maxAge during heavy asset refactors.
Verify stale fix
- Delete a post locally
hugo --gc --minifytest ! -f public/blog/deleted-post/index.html- Deploy
curl -I https://site.com/blog/deleted-post/→ 404- Hard refresh / incognito — no ghost content
CI snippet (complete)
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: peaceiris/actions-hugo@v3
with:
hugo-version: '0.139.4'
extended: true
- run: hugo --gc --minify --buildFuture=false
- run: find public -name '*.html' | wc -l
Result
After enforcing --gc + fingerprint + HTML TTL 600s, "stale content" tickets from editors went to zero over 6 weeks.