Implementing Browser Caching for Better Performance
Learn how browser caching works, how to use Cache-Control headers, what to cache, what not to cache, and how to avoid stale or private content issues.
Introduction
Browser caching helps websites load faster by letting the visitor’s browser reuse files it has already downloaded, such as images, CSS, JavaScript and fonts. Instead of requesting every file again on every visit, the browser can use its local cached copy until the cache rule expires.
Good caching reduces page load time, bandwidth usage and server load. But caching must be configured carefully. Static assets can usually be cached for a long time, while HTML pages, private dashboards, checkout pages and account areas often need shorter or more careful rules.
Quick answer
Use browser caching for static assets like images, CSS, JavaScript and fonts. Set long cache lifetimes for versioned files, shorter or revalidation-based caching for HTML, and avoid public caching for private or personalized pages. Check Cache-Control, Expires, ETag, Last-Modified and CDN cache headers.
Browser caching
Browser caching is the process of storing website files in the user’s browser so they do not need to be downloaded again on every page view.
Common cached files include:
- images
- CSS files
- JavaScript files
- fonts
- icons
- logos
- downloadable assets
- static JSON files
Caching is most useful for files that do not change often, or files that change names when updated.
Browser vs CDN cache
Browser cache and CDN cache are related, but they are not the same.
Browser cache
Stored on the visitor’s device. It helps repeat visits from the same user.
CDN cache
Stored on edge servers near visitors. It helps many users receive content faster.
Origin cache
Stored on your hosting server or application layer. It helps the server generate pages faster.
A website can use all three layers, but each layer needs correct cache rules.
Cache headers
Cache-Control
The main modern header for cache behavior.
Expires
Older header that sets an absolute expiry date.
ETag
A validation token used to check whether a file changed.
Last-Modified
Shows when the resource was last changed.
Age
Shows how long a response has been cached by an intermediary, such as a CDN.
Vary
Tells caches that different versions may exist depending on request headers.
Pragma
Older header sometimes used for legacy no-cache behavior.
Cache-Control basics
Cache-Control is the most important caching header.
Common directives:
- public — response may be stored by browsers and shared caches.
- private — response is intended for a single user and should not be stored by shared caches.
- max-age — how long the browser may reuse the response, in seconds.
- no-cache — the browser may store the response but must revalidate before using it.
- no-store — the browser should not store the response.
- must-revalidate — the cache must confirm freshness after expiry.
- immutable — the file is not expected to change during its cache lifetime.
The best directive depends on whether the content is static, dynamic, public or private.
What to cache
Long browser cache lifetimes work well for static assets, especially when filenames change after updates.
Good candidates:
- versioned CSS files
- versioned JavaScript files
- images
- logos
- icons
- fonts
- downloadable PDFs
- static media
- hashed build assets
Example: app.8f3a91.css, main.91bd72.js
If the filename changes when the file changes, it is safer to use long cache lifetimes.
What not to cache
Some pages should not be cached for long, especially if they change often or contain user-specific information.
Be careful with:
- HTML pages
- account dashboards
- checkout pages
- carts
- admin pages
- login pages
- API responses with user data
- search results
- personalized content
- forms with tokens
- pages that change frequently
Never publicly cache private or user-specific content unless you fully understand the cache rules.
Why this matters
Browser caching matters because repeat visitors should not need to download the same files again and again. Correct caching can make websites feel faster, reduce bandwidth and lower load on the server.
Bad caching can cause the opposite problem: users may see old CSS, broken JavaScript, outdated content or private pages stored in places they should not be stored.
How to check caching
Use HTTP Header Checker to inspect caching headers on different resource types.
Check:
- HTML page — review Cache-Control on the final page response.
- CSS file — check whether CSS has a longer cache lifetime.
- JavaScript file — check whether JS files are versioned and cacheable.
- Images — confirm images use reasonable caching.
- Fonts — check font caching and CORS if needed.
- Private pages — confirm private pages are not publicly cached.
- CDN headers — look for Age, X-Cache, CF-Cache-Status or similar headers.
- Final response — follow redirects and check the final URL users load.
Check cache headers
Use HTTP Header Checker to inspect Cache-Control, Expires, ETag and CDN cache headers on your pages and assets.
Common problems
Static assets not cached
MediumImages, CSS, JS or fonts are downloaded repeatedly.
Next step: Add Cache-Control with appropriate max-age for static assets.
HTML cached too aggressively
HighUsers may see outdated page content after updates.
Next step: Use shorter caching or revalidation for HTML pages.
Private content cached publicly
HighPersonalized or account content may be stored by shared caches.
Next step: Use Cache-Control: private, no-store or appropriate authenticated-page rules.
CSS/JS changes not visible
MediumBrowsers keep using old cached files.
Next step: Use versioned or hashed filenames when assets change.
CDN cache conflicts with browser cache
MediumThe CDN and browser use different caching expectations.
Next step: Align origin headers and CDN cache rules.
Missing cache validation
LowThe browser cannot efficiently check whether a file changed.
Next step: Use ETag or Last-Modified where appropriate.
Too many cache-busting query strings
LowAssets may be harder to cache consistently.
Next step: Prefer versioned filenames where possible.
Fonts not cached well
LowFonts reload repeatedly and delay rendering.
Next step: Set cache headers for font files and preload critical fonts carefully.
API responses cached incorrectly
HighDynamic or user-specific API data may be reused incorrectly.
Next step: Set API cache rules based on privacy and freshness requirements.
Cache not cleared after deployment
MediumUsers or CDN edges still receive old files after updates.
Next step: Purge CDN cache or change asset filenames during deployment.
How to implement
-
Step 1: Separate content types
Treat HTML, static assets, API responses and private pages differently.
-
Step 2: Use long cache for versioned assets
Cache hashed CSS, JS, images and fonts for a long time.
-
Step 3: Use shorter rules for HTML
HTML often needs shorter caching or revalidation.
-
Step 4: Protect private pages
Use private or no-store rules for account, checkout, admin and personalized pages.
-
Step 5: Use asset versioning
Change filenames or build hashes when CSS/JS changes.
-
Step 6: Align CDN and origin
Make sure CDN cache rules respect your intended browser cache behavior.
-
Step 7: Test after deployment
Check whether users receive updated assets after changes.
-
Step 8: Monitor for stale content
Watch for reports of old design, broken scripts or outdated pages.
CDN cache and browser cache should work together.
- CDN cache TTL
- browser max-age
- edge cache status
- cache purge rules
- bypass rules for cookies
- stale-while-revalidate if supported
- HTML vs asset caching
- query string handling
- cache by device or language if needed
CDN cache can be purged centrally, but browser cache on user devices may remain until expiry unless filenames change.
Cache busting means making the browser request a new file when the file changes.
- Better: hashed filenames, versioned filenames, build-generated asset names, updated manifest files.
- Example: style.css → style.2026-06-29.css, app.js → app.a7f91c.js
- Avoid relying only on: manually telling users to clear cache, random query strings everywhere, very short cache times for all assets.
Long cache lifetimes are safest when paired with reliable asset versioning.
Example 1: Good static asset cache
Request:
https://example.com/assets/app.a7f91c.js
Header:
Cache-Control: public, max-age=31536000, immutable
Why it works:
The filename changes when the asset changes.
Example 2: Risky HTML cache
Request:
https://example.com/pricing
Header:
Cache-Control: public, max-age=31536000
Risk:
Users may see old pricing page content for too long.
Better:
Cache-Control: no-cache
Example 3: Private page
Request:
https://example.com/account
Header:
Cache-Control: no-store
Why it works:
The browser and shared caches should not store private account content.
Examples are illustrative. Use rules that match your content freshness and privacy needs.
Check headers:
curl -I https://example.com
Check CSS headers:
curl -I https://example.com/assets/style.css
Check JS headers:
curl -I https://example.com/assets/app.js
Check image headers:
curl -I https://example.com/images/logo.png
Look for:
cache-control
expires
etag
last-modified
age
x-cache
cf-cache-status
Command examples show response headers. Browser developer tools are useful for seeing whether resources are loaded from memory cache, disk cache, network or CDN.
Example cache rules
Static versioned assets:
Cache-Control: public, max-age=31536000, immutable
Images:
Cache-Control: public, max-age=2592000
HTML page:
Cache-Control: no-cache
Private account page:
Cache-Control: private, no-store
API response with user data:
Cache-Control: no-store
Public API response:
Cache-Control: public, max-age=300
These examples are illustrative. Cache rules depend on your site, framework, CDN, privacy requirements and update process.
WordPress caching
WordPress caching can be handled by hosting, server rules, CDN, cache plugin or performance plugin.
Check:
- cache plugin settings
- page cache rules
- browser cache settings
- CDN integration
- CSS/JS versioning
- image optimization plugin
- WooCommerce cart/checkout exclusions
- logged-in user exclusions
- admin page exclusions
- query string behavior
- cache purge after updates
For WooCommerce or membership sites, make sure cart, checkout, account and logged-in pages are excluded from public cache.
Frequently asked questions
What is browser caching?
Browser caching stores website files on the visitor’s device so they can be reused on later visits.
What should be cached for a long time?
Versioned static assets such as images, CSS, JavaScript and fonts are usually good candidates.
Should HTML pages be cached for a long time?
Usually no. HTML often changes more frequently and may need revalidation.
What is Cache-Control?
Cache-Control is the main HTTP header that tells browsers and caches how to store and reuse a response.
What does immutable mean?
It tells the browser the file will not change during its cache lifetime, useful for hashed assets.
Can caching break a website?
Yes. Bad caching can show stale content, old CSS/JS or private data in unsafe places.
How do I update cached CSS or JavaScript?
Use versioned or hashed filenames so browsers request the new file after deployment.
Related tools
Use these free tools to verify your configuration after applying changes.
Related guides
Browse all Website Health guides →Need help applying this fix?
Send us your domain, report link or issue details. CheckDomainHealth will review the request and route it to the right technical team if hands-on support is needed.
Was this guide helpful?
Your feedback helps us improve our guides for everyone.
Thanks for your feedback!