Hugo caching strategies are essential for maximizing the performance of your static site generator. While Hugo generates static files that are inherently fast, implementing proper caching at multiple layers can dramatically improve build times, reduce server load, and enhance user experience.
Whether you’re using a popular theme from our Most popular themes for Hugo guide or a custom theme, these caching strategies will help optimize your site’s performance.
This comprehensive guide covers build-time caching, incremental builds, CDN optimization, HTTP headers, and asset caching strategies to help you achieve optimal performance for your Hugo-based website.
This nice image is generated by AI model Flux 1 dev.
Understanding Hugo’s Build Cache
Hugo maintains an internal build cache that stores processed content and assets to speed up subsequent builds. This cache is located in the resources/_gen directory and includes:
- Rendered templates: Pre-processed template output
- Processed images: Resized, optimized, and converted images
- Compiled assets: Minified CSS and JavaScript
- Resource metadata: File hashes and processing results
How Build Cache Works
When you run hugo, the generator:
- Checks the cache for existing processed resources
- Compares file modification times and content hashes
- Skips processing unchanged files
- Only rebuilds modified or new content
This means that for a site with 1000 posts, editing a single post only requires Hugo to process that one post and regenerate affected pages, not the entire site.
Managing the Build Cache
You can control Hugo’s cache behavior using various command-line flags. For a comprehensive reference of Hugo commands, see the Hugo Cheat Sheet:
# Clear the cache and rebuild everything
hugo --ignoreCache
# Use a custom cache directory
export HUGO_CACHEDIR=/path/to/cache
hugo
# Disable fast render mode (forces full rebuild)
hugo server --disableFastRender
For CI/CD pipelines, consider persisting the cache directory between builds to speed up deployments. If you’re using Gitea Actions for deployment, see our guide on Using Gitea Actions deploy Hugo website to AWS S3 for a complete CI/CD setup:
# Example GitHub Actions workflow
- name: Cache Hugo resources
uses: actions/cache@v3
with:
path: resources/_gen
key: ${{ runner.os }}-hugo-${{ hashFiles('**/content/**') }}
Configuring File Caches
Hugo provides granular control over different cache types through the [caches] configuration section. According to the Hugo documentation, you can configure multiple cache types:
[caches]
[caches.assets]
dir = ':resourceDir/_gen'
maxAge = -1
[caches.getcsv]
dir = ':cacheDir/:project'
maxAge = -1
[caches.getjson]
dir = ':cacheDir/:project'
maxAge = -1
[caches.getresource]
dir = ':cacheDir/:project'
maxAge = -1
[caches.images]
dir = ':resourceDir/_gen'
maxAge = -1
[caches.misc]
dir = ':cacheDir/:project'
maxAge = -1
[caches.modules]
dir = ':cacheDir/modules'
maxAge = -1
Cache Types Explained
-
assets: Caches processed CSS, JavaScript, and other assets from Hugo Pipes -
getcsv: Caches parsed CSV files loaded viagetCSVfunction -
getjson: Caches parsed JSON files loaded viagetJSONfunction -
getresource: Caches remote resources fetched viagetResourcefunction -
images: Caches processed images (resized, optimized, converted) -
misc: General-purpose cache for miscellaneous operations -
modules: Caches Hugo modules and their dependencies
Configuration Options
Each cache type supports two configuration options:
-
dir: The absolute file system path where cached files are stored. You can use tokens:-
:cacheDir– Replaced with the configured cache directory -
:resourceDir– Replaced with the resource directory (typicallyresources/_gen) -
:project– Replaced with the base directory name of the current Hugo project
-
-
maxAge: The duration a cached entry remains valid before being evicted:-
0– Disables the cache -
-1– Cache entry never expires (default) - Positive number – Cache expires after specified duration (e.g.,
3600for 1 hour)
-
Custom Cache Configuration Example
You can customize cache settings for specific use cases:
[caches]
# Keep processed images cached indefinitely
[caches.images]
dir = ':resourceDir/_gen/images'
maxAge = -1
# Cache JSON API responses for 1 hour
[caches.getjson]
dir = ':cacheDir/:project/json'
maxAge = 3600
# Cache remote resources for 24 hours
[caches.getresource]
dir = ':cacheDir/:project/resources'
maxAge = 86400
This configuration allows you to:
- Keep processed images cached permanently (since they’re deterministic)
- Refresh JSON data every hour (for dynamic content)
- Cache remote resources for 24 hours (balance between freshness and performance)
The :project token ensures each Hugo project has isolated caches, so running hugo --gc (garbage collection) only affects the current project’s cache.
Incremental Builds
Hugo’s incremental build system is one of its most powerful features. It tracks changes at the file level and only rebuilds what’s necessary.
Enabling Incremental Builds
Incremental builds are enabled by default. Hugo automatically:
- Tracks file dependencies
- Rebuilds only changed pages and their dependencies
- Maintains dependency graphs for efficient updates
Build Performance Tips
-
Use
hugo serverfor development: The development server uses incremental builds automatically -
Leverage
--minifyonly in production: Minification adds overhead; use it only for final builds - Optimize image processing: Use Hugo’s image processing features efficiently:
[imaging]
bgColor = '#ffffff'
hint = 'photo'
quality = 75
resampleFilter = 'box'
- Limit resource processing: Only process images and assets that are actually used
CDN Caching Strategies
Content Delivery Networks (CDNs) are crucial for global performance. When deploying Hugo sites to CDNs like CloudFront, Cloudflare, or Netlify, configure caching appropriately. For detailed instructions on deploying your Hugo site to AWS S3 with CloudFront, see our guide on Deploy Hugo-generated website to AWS S3.
CloudFront Configuration
For AWS CloudFront deployments, configure cache behaviors:
# config.toml
[[deployment.targets]]
name = "production"
URL = "s3://your-bucket?region=us-east-1"
cloudFrontDistributionID = "E1XIDGUJGD9BU9"
Create CloudFront cache behaviors:
-
Static assets (
.css,.js,.jpg,.png, etc.):- TTL: 1 year (31536000 seconds)
- Cache Policy: CachingOptimized
- Compress: Yes
-
HTML pages (
.html):- TTL: 1 hour (3600 seconds)
- Cache Policy: CachingDisabled (with origin headers)
- Compress: Yes
Cache Invalidation
Automate cache invalidation on deployments:
# Invalidate CloudFront cache after deployment
aws cloudfront create-invalidation
--distribution-id E1XIDGUJGD9BU9
--paths "/*"
Or use Hugo’s deployment feature:
[[deployment.targets]]
name = "production"
URL = "s3://your-bucket"
cloudFrontDistributionID = "E1XIDGUJGD9BU9"
Hugo will automatically invalidate the cache when deploying.
Asset Optimization and Caching
Hugo provides built-in asset processing that integrates with caching.
Resource Hashing
Hugo can automatically add content hashes to filenames:
{{ $css := resources.Get "css/main.css" | minify | fingerprint }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}">
This generates filenames like main.min.abc123def456.css, enabling long-term caching since the hash changes when content changes.
Image Processing and Caching
Process images efficiently using Hugo’s built-in image processing. Hugo caches processed images, so resizing the same image multiple times only processes it once. For more advanced image handling, including OpenGraph image metadata generation, see our guide on Opengraph image metadata in Hugo static site generator:
{{ $image := resources.Get "images/photo.jpg" }}
{{ $resized := $image.Resize "800x600" }}
<img src="{{ $resized.RelPermalink }}" alt="Photo">
Asset Bundling
Bundle and minify assets:
{{ $css := slice
(resources.Get "css/reset.css")
(resources.Get "css/main.css")
(resources.Get "css/components.css")
| resources.Concat "css/bundle.css"
| minify
| fingerprint
}}
<link rel="stylesheet" href="{{ $css.RelPermalink }}">
This creates a single cached, minified, and fingerprinted CSS file.
Service Worker Caching (Optional)
For advanced caching strategies, consider implementing service workers:
Basic Service Worker
// sw.js
const CACHE_NAME = 'hugo-site-v1';
const urlsToCache = [
'/',
'/css/main.css',
'/js/main.js',
'/images/logo.png'
];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => cache.addAll(urlsToCache))
);
});
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then((response) => response || fetch(event.request))
);
});
Register Service Worker
<!-- In your Hugo template -->
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
</script>
Monitoring and Optimization
Build Time Monitoring
Track build performance:
# Time your builds
time hugo
# Use verbose output to see what's being processed
hugo --verbose
Cache Hit Rates
Monitor CDN cache hit rates through your CDN’s analytics dashboard. Aim for:
- Static assets: >95% cache hit rate
- HTML pages: 60-80% cache hit rate (depending on update frequency)
Performance Testing
Use tools like:
- Lighthouse: Test caching effectiveness
- WebPageTest: Analyze cache headers
- GTmetrix: Monitor performance metrics
Best Practices Summary
- Enable Hugo’s build cache: Let Hugo cache processed resources
- Use incremental builds: Only rebuild what’s changed
- Configure CDN properly: Long TTLs for assets, shorter for HTML
-
Set appropriate HTTP headers: Use
immutablefor hashed assets - Fingerprint assets: Add content hashes to filenames
- Invalidate cache on deployments: Ensure users see updates
- Monitor performance: Track build times and cache hit rates
- Optimize images: Use Hugo’s image processing efficiently
- Bundle assets: Reduce HTTP requests with bundled CSS/JS
- Consider service workers: For offline-first or advanced caching needs
Conclusion
Effective caching strategies for Hugo sites involve multiple layers: build-time caching for faster development, CDN caching for global performance, and proper HTTP headers for browser caching. By implementing these strategies, you can achieve:
- Faster builds: Incremental builds and build cache reduce build times
- Better performance: CDN and browser caching improve load times
- Reduced server load: Static assets cached at the edge
- Improved user experience: Faster page loads and offline capabilities
Remember that caching is a balance between performance and freshness. Static assets can be cached aggressively, while HTML should have shorter cache times to ensure content updates are visible quickly.
Useful Links
- Hugo Documentation – Performance
- Hugo Documentation – Image Processing
- Hugo Documentation – Asset Management
- CloudFront Caching Best Practices
- Hugo Cheat Sheet
- Most popular themes for Hugo
- Using Gitea Actions deploy Hugo website to AWS S3
- Opengraph image metadata in Hugo static site generator
- Deploy Hugo-generated website to AWS S3

