Caching Basics Every Web Developer Should Know
Your users just clicked a button, and nothing happened for three seconds. The database query finished, the server responded, but the same data that loaded yesterday had to travel across the entire internet again. This is the problem caching solves.
Understanding HTTP caching basics isn’t optional for frontend developers. It’s the difference between a snappy application and one that feels broken. This guide covers what you need to know about browser cache vs. CDN cache, Cache-Control headers, and validation mechanisms like ETag and Last-Modified.
Key Takeaways
- Set explicit
Cache-Controlheaders on every response to avoid unpredictable browser heuristics. - Use long
max-agevalues paired with cache busting (content-hashed filenames) for static assets. - Use
no-cachewith ETag or Last-Modified for content that must stay fresh. - Always mark personalized or authenticated content as
privateto prevent data leaking through shared caches.
What Is Caching and Why It Matters
Caching stores a copy of data closer to where it’s needed. When your browser requests an image, it can save that image locally. The next request skips the network entirely.
The performance gains are dramatic. For example, a database query might take tens of milliseconds, while reading from a browser cache is typically near-instant and avoids a network round trip entirely.
Caching delivers three core benefits:
- Reduced latency: Data travels shorter distances.
- Lower server load: Fewer requests reach your origin.
- Better user experience: Pages load faster on repeat visits.
Understanding Cache Layers
Requests pass through multiple caches before reaching your server. Each layer serves a different purpose.
Browser Cache (Private Cache)
The browser cache sits on the user’s device. It stores responses that only that user should see. When you mark a response as private, it stays here and never gets shared with other users.
This is where personalized content belongs — user profiles, authenticated API responses, anything tied to a specific session.
CDN Cache (Shared Cache)
A CDN cache sits between users and your origin server, distributed across geographic locations. When a user in Tokyo requests your JavaScript bundle, the CDN serves it from a nearby edge server instead of your origin data center.
CDNs excel at caching static assets: images, CSS, JavaScript, and fonts. They can also cache public API responses, though this requires careful configuration.
Server-Side Caching
Beyond HTTP caching, servers often maintain their own caches using tools like Redis or Memcached. As a frontend developer, you won’t configure these directly, but understanding they exist helps you reason about why some API responses are faster than others.
Discover how at OpenReplay.com.
Cache-Control Headers: The Core Directives
The Cache-Control header tells caches how to handle responses. These are the directives you’ll use most often:
| Directive | Meaning |
|---|---|
max-age=3600 | Cache for 3600 seconds (1 hour) |
no-cache | Store it, but revalidate before using |
no-store | Don’t store this response anywhere |
private | Only the browser cache may store this |
public | Any cache can store this |
A common mistake: no-cache doesn’t mean “don’t cache.” It means “always check with the server before using the cached copy.” Use no-store when you truly want no caching at all.
For static assets with hashed filenames, use aggressive caching:
Cache-Control: public, max-age=31536000
For HTML pages that change frequently (and especially for sensitive or highly dynamic content):
Cache-Control: no-cache, private
ETag and Last-Modified: Validation Mechanisms
When cached content expires, browsers don’t always need to download everything again. Validation headers enable efficient revalidation.
Last-Modified contains a timestamp. On subsequent requests, the browser sends an If-Modified-Since header with that timestamp. If nothing changed, the server returns 304 Not Modified — no body, minimal bandwidth.
ETag contains a unique identifier (often a content hash). On subsequent requests, the browser sends an If-None-Match header with that identifier. Same result: a 304 if the content is unchanged.
ETags are more precise than timestamps because they detect actual content changes, not just file modification times. A file could be re-saved without changing its content, updating its timestamp but not its ETag.
Cache Busting for Static Assets
You want static assets cached for as long as possible, but you also need users to get updates when you deploy. Cache busting solves this by changing the URL when content changes.
Modern build tools append content hashes to filenames:
bundle.a1b2c3d4.js
styles.e5f6g7h8.css
When you deploy new code, the hash changes, the URL changes, and browsers fetch the new version. The old cached files simply expire naturally.
Common Pitfalls to Avoid
Caching authenticated content publicly: Always use private for user-specific data. Leaking one user’s data to another through a shared cache is a serious security issue.
Over-caching API responses: Dynamic data needs short TTLs or no-cache. Stale prices during checkout cause real problems.
Forgetting to set headers: Without explicit Cache-Control headers, browsers may apply heuristic caching based on response metadata, which can lead to behavior you didn’t intend.
Conclusion
Caching isn’t something you configure once and forget. Set explicit Cache-Control headers on every response. Pair long max-age values with content-hashed filenames for static assets. Use no-cache alongside ETag or Last-Modified for content that must stay fresh, and always mark personalized content as private. Check your headers in DevTools, verify your CDN behavior, and test what users actually experience.
FAQs
no-cache tells the browser it can store the response but must revalidate with the server before using it. no-store tells the browser not to save the response at all. Use no-store for sensitive data like banking details, and no-cache for content that changes often but benefits from conditional revalidation.
Open your browser DevTools, go to the Network tab, and select any request. The Response Headers section shows Cache-Control, ETag, and Last-Modified values. Look for the size column too. If it says disk cache or memory cache, the response was served from the browser cache rather than the network.
It depends on the data. Public, rarely changing data like product categories can use short max-age values. User-specific or frequently changing data should use no-cache with validation headers or no-store. Always mark authenticated responses as private to prevent CDNs from serving one user’s data to another.
Content hashes let you set very long cache lifetimes for static assets while still delivering updates instantly. When file content changes, the hash changes, producing a new URL that bypasses any existing cache. This technique is called cache busting and is the standard approach used by tools like Webpack, Vite, and Rollup.
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.