Optimagio

Cache-Control Headers for Images: Optimize Browser & CDN Caching

Learn how to configure precise Cache-Control headers for different image types to maximize caching efficiency, reduce origin load, and improve delivery speed.

Optimagio Team 4 min read
Cache-Control Headers for Images: Optimize Browser & CDN Caching

When users visit your website, images often account for the majority of downloaded bytes and significantly impact loading times. Proper caching configuration through Cache-Control headers can dramatically reduce server load, decrease bandwidth costs, and improve user experience by serving images from local browser caches or nearby CDN edges rather than fetching them from your origin server repeatedly.

Understanding Cache-Control Directives

Cache-Control headers consist of multiple directives that control caching behavior. The most important directives for image optimization include:

max-age
Specifies the maximum time in seconds that a resource can be cached by the browser
s-maxage
Similar to max-age but applies only to shared caches (CDNs, proxies)
public
Indicates the response can be cached by any cache, including CDNs and browsers
private
Limits caching to the user's browser only, preventing CDN caching
no-cache
Forces validation with the origin server before using cached content
no-store
Prevents caching entirely at all levels
must-revalidate
Requires caches to validate stale resources with the origin server
immutable
Tells browsers the resource will never change during its max-age period

Optimal Settings for Different Image Types

Different types of images require different caching strategies. Here's how to configure Cache-Control headers for common scenarios:

Static Assets (Logos, Icons, UI Graphics)Use long-term caching with content hashing in filenames. Set max-age=31536000 (1 year) and include immutable directive. These assets rarely change and benefit from permanent caching.
Dynamic Content (Product Images, Blog Photos)Use moderate caching with revalidation. Set max-age=86400 (1 day) with must-revalidate. This balances caching benefits with content freshness requirements.
User-Generated Content (Avatars, Uploads)Use shorter caching periods. Set max-age=3600 (1 hour) with must-revalidate. This ensures relatively fresh content while still reducing origin load.
# Nginx configuration for static assets
location ~* \.(jpg|jpeg|png|gif|ico|webp|avif)$ {
    add_header Cache-Control "public, immutable, max-age=31536000";
}

# Apache .htaccess for static images
<FilesMatch "\.(jpg|jpeg|png|gif|ico|webp|avif)$">
    Header set Cache-Control "public, immutable, max-age=31536000"
</FilesMatch>

CDN vs Browser Caching Strategies

Effective caching requires understanding the difference between browser caching (private cache) and CDN caching (shared cache). While browsers serve individual users, CDNs serve multiple users from edge locations.

AspectBrowser CacheCDN Cache
ScopeSingle userMultiple users
ControlCache-Control headersCache-Control + CDN settings
Typical DurationHours to daysMinutes to weeks
ValidationIf-modified-since/ETagSame + CDN-specific rules
Best ForRepeat visitsFirst-time visits from nearby users

Implementation and Testing

Implementing Cache-Control headers varies by web server and requires thorough testing to ensure proper behavior. Here's how to set up and verify your caching strategy:

  1. 1Configure your web serverSet Cache-Control headers based on file type and location using server configuration files (nginx.conf, .htaccess, web.config)
  2. 2Use content-based filenamesInclude content hashes in filenames for static assets to enable immutable caching without worrying about stale content
  3. 3Test with browser toolsUse browser developer tools to verify headers are set correctly and resources are being served from cache
  4. 4Monitor cache hit ratesUse CDN analytics and server logs to monitor cache performance and adjust strategies as needed

Advanced Caching Techniques

Beyond basic Cache-Control headers, several advanced techniques can further optimize image delivery and caching efficiency.

Stale-while-revalidate
  • BenefitServes stale content immediately while revalidating in background
  • Use CasePerfect for content where freshness is important but not critical
  • ImplementationCache-Control: max-age=3600, stale-while-revalidate=86400
Vary Header
  • BenefitControls caching based on request headers (Accept, Accept-Encoding)
  • Use CaseWhen serving different image formats (WebP vs JPEG) to different browsers
  • ImplementationVary: Accept, Accept-Encoding

Automate image optimization with Optimagio

Doing this by hand for every image does not scale. Optimagio optimizes and converts your images (WebP and AVIF) automatically across your API, web app, and CMS — so every page ships the smallest possible files without manual work. See plans and pricing →

FAQ

Frequently asked questions

What is the difference between max-age and s-maxage?

max-age controls browser caching duration, while s-maxage controls CDN/shared cache duration. Use s-maxage when you want CDNs to cache content longer than browsers.

Should I use immutable for all images?

Use immutable only for static assets with content-based hashing in filenames. For dynamic or frequently updated images, avoid immutable as it prevents revalidation.

How do I force a cache refresh for updated images?

Change the filename (content hash) or URL parameters for immutable assets. For non-immutable assets, use must-revalidate and set appropriate max-age values.

What Cache-Control header should I use for user-generated content?

Use shorter max-age values (hours rather than days/weeks) with must-revalidate to ensure freshness while still benefiting from caching.

How can I test if my Cache-Control headers are working?

Use browser developer tools Network tab to check response headers and the Size column to verify cache status (from memory cache, from disk cache).

Keep reading