If youβre building anything for the web-APIs, SPAs, static sites-your performance heavily depends on proper caching. The Cache-Control header is the core of HTTP caching. It tells browsers, CDNs, and reverse proxies exactly how to cache your response.
Letβs break it down without the noise.
What Does Cache-Control Do?
It defines caching rules:
- how long something can stay cached
- who can cache it
- whether it requires revalidation
- whether itβs allowed to be stored at all
You attach it to your response like this:
Cache-Control: max-age=3600, public
This says: βCache this for 1 hour. Anyone can store it.β
Common Cache-Control Directives
1. max-age
How long (in seconds) the resource should be cached.
Cache-Control: max-age=86400
1 day.
2. public vs private
-
public: CDNs, proxies, browsers - everyone can cache. -
private: Only the userβs browser can cache it. Use it for anything tied to a specific user.
Example:
Cache-Control: private, max-age=600
3. no-cache
The content can be cached, but must be revalidated before use.
Cache-Control: no-cache
Itβs misleading. It doesnβt block caching. It blocks using the cached version without checking with the server.
4. no-store
The nuclear option.
Cache-Control: no-store
Nothing is cached. Useful for:
- payment pages
- personal data
- login tokens
- dashboards
5. must-revalidate
Forces the cache to revalidate when expired.
Cache-Control: max-age=0, must-revalidate
Good for data that must always be fresh.
6. immutable
For assets that never change.
Cache-Control: max-age=31536000, immutable
Tells the browser: βDonβt even try revalidating. This file will never change.β
Perfect for:
- hashed JS bundles
- images with versioned filenames
Best Practices
Static Assets (JS, CSS, images)
If you use hashed filenames:
Cache-Control: public, max-age=31536000, immutable
Fastest possible web experience.
API Responses
Most APIs shouldnβt be cached globally:
Cache-Control: private, max-age=0, no-cache
For public APIs (weather, news, etc.):
Cache-Control: public, max-age=60
HTML Pages
If content changes often:
Cache-Control: no-cache
SPAs with versioned assets:
Cache-Control: no-cache, must-revalidate
Examples
Express.js
jsapp.get("/api/data", (req, res) => {
res.set("Cache-Control", "private, max-age=0, no-cache");
res.json({ ok: true });
});
Nginx
nginxlocation /static/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
Go
gow.Header().Set("Cache-Control", "public, max-age=60")
Why Cache-Control Matters
- Faster page loads
- Lower server load
- Cheaper CDN bills
- Better SEO (Core Web Vitals)
- Avoids stale or incorrect content
Caching is easy to ignore but painful to fix when misconfigured.
Conclusion
Cache-Control gives you fine-grained control over how your app is cached across the web. Use it well, and your site becomes fast, cheap, and stable. Use it badly, and youβll serve stale HTML or hammer your servers for no reason.
Album of the blog:




