Images on a company website are often the heaviest files—and the ones browsers fetch again and again on return visits. Without a clear Cache-Control policy, browsers and CDNs do not know how long they may keep each JPG or WebP. The result is extra latency, wasted bandwidth, and sometimes outdated photos after a rebrand.
This guide covers HTTP headers for static images, how to pair max-age with immutable, what your CDN should mirror, and mistakes to avoid on corporate sites.
What Cache-Control means for static images
Cache-Control tells browsers, proxies, and CDNs whether they may store a response and for how long. For files under /storage, /img, or fingerprinted build assets, the usual goal is long-lived caching because the bytes do not change while the URL stays the same.
It does not replace image weight optimization or modern formats, but it amplifies those wins for returning visitors and multi-page sessions.
Why it matters on company websites
B2B and corporate sites reuse many assets: logos, team photos, service heroes, case-study screenshots. Without caching:
- Every page re-downloads the same blog thumbnails or headshots.
- Origin servers work harder than necessary when a CDN could serve the edge copy.
- Mobile users and Lighthouse scores look worse on the second visit than they should.
A consistent policy also cuts hosting cost and helps users on slower networks.

Recommended headers for fingerprinted images
When filenames include a hash or version (hero-v3.a4f2c9.webp), a safe pattern is:
Cache-Control: public, max-age=31536000, immutable
public allows shared caches. max-age=31536000 (one year) is common for immutable assets. immutable tells clients not to revalidate on every scroll while the URL is unchanged.
If you overwrite files without changing names, skip immutable, use a shorter max-age, or rename on deploy.
CMS images without hashes: freshness vs speed
Blog, team, or product photos edited in a CMS often keep the same URL. Balance with:
Cache-Control: public, max-age=86400(24h) ormax-age=604800(7d) based on update cadence.- CDN purge when an image is replaced.
- Preload only the LCP hero—not every gallery tile.
Document who purges CDN cache after editorial changes so new art does not fight stale edges.
ETag, Last-Modified, and CDNs
Servers may also send ETag or Last-Modified. For versioned URLs, long max-age is often enough. For CMS images, valid ETags enable 304 Not Modified and save full JPG transfers.
Align CDN TTL with origin headers—avoid origin saying one year while the edge expires in one hour.
Common mistakes
- Cache-Control: no-store site-wide. Copied from dynamic HTML and applied to static images—nothing ever caches.
- Huge max-age without versioning. You swap the team photo but visitors keep the old one for days.
- Forgetting CDN purge on deploy. Origin is correct; edge is stale.
- Mixing HTML and image policies. Laravel pages may be
no-cache; JPGs under/storageshould be cacheable. - Lazy-loading the LCP hero. Cache does not fix bad priorities—review lazy loading.

Quick checklist
- Do hashed assets use long
max-ageandimmutable? - Do CMS photos use TTL that matches editorial pace plus CDN purge?
- Do Apache/Nginx send different headers for
/storagevs HTML? - In DevTools → Network, does a repeat visit hit disk cache or 304?
- After a rebrand, did you rename files or invalidate caches?
Conclusion
Well-tuned Cache-Control turns already-optimized images into assets that barely hurt repeat visits. It is a small infrastructure change with outsized impact on perceived speed and cost.
If you want help reviewing headers, CDN rules, and CMS publishing for your company site, aatsoft can audit origin, edge, and workflow with you.