NNicheStackTutorials
← All tutorials
Hugo

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.

·9 min read·Hugo
Clear Hugo Cache & Fix Stale Content After Deploy cover

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

  1. resources/ processed asset cache (in public/ hashes)
  2. :cacheDir (modules, images) — default OS temp
  3. 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

  1. Delete a post locally
  2. hugo --gc --minify
  3. test ! -f public/blog/deleted-post/index.html
  4. Deploy
  5. curl -I https://site.com/blog/deleted-post/ → 404
  6. 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.

Tags: HugoCacheBuildDevOps