What is caching? Browser, CDN, server, and database caching explained
How caching works at every layer of the web — browser cache, CDN edge cache, server-side cache, and database cache — and when each one matters for speed and scalability.
On this page
- Why caching exists
- The four layers of web caching
- 1. Browser cache (private cache)
- 2. CDN edge cache (shared cache)
- 3. Server-side cache (application cache)
- 4. Database cache
- Cache invalidation: the hard problem
- Caching and compression work together
- When to use which cache
- FAQ
- What is the difference between a cache hit and a cache miss?
- How does Redis differ from Memcached?
- What is cache invalidation?
- Can caching cause problems?
- Summary
Caching is the practice of storing a copy of data so that future requests can be served faster. Without caching, every request for the same piece of information would require recomputing it or reading it from the original source — which is slower and more expensive. Caching appears at every layer of the modern web stack, from your browser to the database, and understanding how each layer works helps you build faster, more scalable applications.
Why caching exists
Accessing data from cache is orders of magnitude faster than recomputing or re-reading it. A cache hit — a request served from cache — avoids a network round-trip, reduces database load, and delivers a response in microseconds. The more cache hits a system gets, the less load it places on its backing store and the more users it can handle with the same infrastructure.
Caches work because of locality of reference: programs tend to access the same data repeatedly (temporal locality) and data that is nearby in storage is often accessed together (spatial locality). By predicting which data will be reused, caches eliminate redundant work.
The four layers of web caching
1. Browser cache (private cache)
The browser cache is a private store on your device. When your browser downloads a file — an image, a stylesheet, a JavaScript file, a font — it keeps a copy. On your next visit, the browser reuses that copy instead of downloading it again.
Each cached entry has a lifetime, controlled by HTTP headers:
Cache-Control: max-age=31536000— the server says this file is good for one year. Within that window, the browser uses the cached copy without asking.Cache-Control: no-store— the server forbids caching; the browser never stores this response.Cache-Control: no-cache— the browser may store the file, but must ask the server ("is this still valid?") before using it.ETag/Last-Modified— validation tokens. When the browser revalidates, the server answers304 Not Modifiedif the file has not changed, avoiding a full re-download.
For more detail, see What is a browser cache?.
2. CDN edge cache (shared cache)
A content delivery network (CDN) places cache servers at dozens or hundreds of locations worldwide. When a visitor requests a file, the CDN serves it from the nearest edge server rather than your origin server. For the first visitor in a region, the CDN fetches the file from the origin and caches a copy at the edge. All subsequent visitors in that region get the cached copy.
CDNs dramatically reduce latency for global audiences because the cache is physically close to users. They also reduce origin load — the CDN handles most requests, so your server only receives cache misses.
CDNs use HTTP caching headers just like the browser cache, but they operate on shared infrastructure. Cloudflare, Fastly, and Akamai are prominent CDN providers.
For more detail, see What is a CDN?.
3. Server-side cache (application cache)
Server-side caching stores the results of expensive operations — database queries, API calls, template rendering — in memory so they can be reused without recomputing. Unlike the browser and CDN caches (which serve pre-computed HTTP responses), a server-side cache sits inside your application logic.
Common server-side caches:
- Object cache — stores results of database queries or complex computations. Redis and Memcached are popular in-memory key-value stores used for this purpose. Redis (Remote Dictionary Server) is an in-memory key-value database, released in 2009, used as a distributed cache and message broker. Memcached, released in 2003, is a general-purpose distributed memory caching system.
- Full-page cache — stores complete HTML pages (or fragments) so they can be served without running application code or querying the database.
- OPcache (PHP) — caches precompiled script bytecode, eliminating the overhead of parsing and compiling PHP on every request.
- CDN as a cache — a reverse proxy or CDN in front of your application server can cache entire pages or API responses.
Server-side caches are invalidated when the underlying data changes. A product page cache, for example, must be cleared when the product price changes. Strategies include time-based expiration (TTL), event-driven invalidation, and cache tagging (grouping keys by content type so an entire category can be flushed at once).
4. Database cache
Databases maintain internal caches of query results and recently accessed pages. The database buffer pool holds frequently read data pages in memory; indexes reduce the amount of data that must be scanned on each query.
For more detail, see What is a database index?.
Beyond the database's own cache, external caches like Redis sit between the application and the database to absorb repeated queries. A product catalog that is read ten thousand times per minute does not need ten thousand database queries — one query cached in Redis for a few seconds covers all of them.
Cache invalidation: the hard problem
Caching is only useful if the cached data stays current. Cache invalidation is the process of removing or updating stale entries. The two main strategies:
- TTL (time-to-live) — set an expiration time. Simple, but data can be stale until the TTL expires.
- Event-driven invalidation — when data changes, your application explicitly removes the corresponding cache entry. This keeps data fresh but requires more infrastructure logic.
The famous quip from Phil Karlton — "there are only two hard things in computer science: cache invalidation and naming things" — captures why this remains one of the most challenging problems in distributed systems.
Caching and compression work together
Caching and compression are often deployed together. A CDN can cache a gzipped or Brotli-compressed response and serve it to all subsequent visitors, combining the speed of cache hits with the bandwidth savings of compression. For more, see Web compression: how gzip and Brotli shrink the web.
When to use which cache
| Situation | Cache layer |
|---|---|
| Static assets (images, fonts, CSS, JS) | Browser + CDN |
| Frequently read database queries | Server-side (Redis, Memcached) |
| Rendered HTML pages | CDN or reverse proxy |
| Full-page app fragments | Server-side cache |
| Reverse proxy and load balancing | Server cache (Nginx, Varnish) |
For more on reverse proxies and caching, see How to set up a reverse proxy with Nginx.
FAQ
What is the difference between a cache hit and a cache miss?
A cache hit occurs when the requested data is found in the cache — the request is served from cache with no backend access. A cache miss occurs when the data is not in the cache — the system must fetch or compute the data from the original source, which is slower. The cache hit rate (percentage of requests served from cache) is a key performance metric for any caching system.
How does Redis differ from Memcached?
Both are in-memory key-value stores used for caching, but they differ in capabilities. Redis supports richer data structures (strings, lists, sets, sorted sets, hashes, bitmaps, hyperloglogs, geospatial indexes, and streams) and can optionally persist data to disk. Memcached is simpler — it stores only string values and has no persistence. Redis also supports replication, clustering, and Lua scripting. Memcached's simplicity can be an advantage when raw speed and memory efficiency are the only goals. Redis is the more common choice for modern applications.
What is cache invalidation?
Cache invalidation is the process of removing or updating cached entries when the underlying data changes. Without invalidation, a cache serves stale (outdated) data. The two main approaches are TTL-based expiration (automatic removal after a set time) and event-driven invalidation (explicit removal when data changes in the database or backing store). Event-driven invalidation is more complex but provides fresher data.
Can caching cause problems?
Yes. A misconfigured cache that serves stale data can make a site appear broken — users see old prices, old content, or old designs. Cache stampedes occur when many requests arrive at once after a cache expires, overwhelming the origin server with simultaneous requests for the same data. Cache poisoning (injecting malicious data into a cache) is a security concern in shared cache environments. Careful TTL settings, cache busting, and event-driven invalidation mitigate these risks.
Summary
Caching is the practice of storing copies of data at every layer of the web stack — browser, CDN, application server, and database — so that repeat requests can be served faster and with less load on the backing store. Each layer serves a different purpose: the browser cache speeds up repeat visits on the same device, a CDN brings content close to users worldwide, a server-side cache reduces database queries, and a database cache minimizes disk reads. The challenge in any caching system is keeping the cache in sync with the source of truth — a problem known as cache invalidation.
Sources
- MDN — HTTP caching (developer.mozilla.org/en-US/docs/Web/HTTP/Caching
- CC-BY-SA 2.5+)
- Wikipedia — Cache (computing) (en.wikipedia.org/wiki/Cache_(computing)
- CC BY-SA 4.0)
- Wikipedia — Content delivery network (en.wikipedia.org/wiki/Content_delivery_network
- CC BY-SA 4.0)
- Wikipedia — Redis (en.wikipedia.org/wiki/Redis
- CC BY-SA 4.0)
- Wikipedia — Memcached (en.wikipedia.org/wiki/Memcached
- CC BY-SA 4.0)
Share this guide
Related guides
- What is code splitting? How it works and when to use it
Code splitting divides a JavaScript bundle into smaller chunks that load on demand, speeding up initial page load. This guide explains the technique, the tools, and when it matters most.
- What are Core Web Vitals? LCP, INP, and CLS explained
Core Web Vitals are a set of Google metrics that measure the real-user experience of a web page: loading, interactivity, and visual stability. Learn what LCP, INP, and CLS measure, their target thresholds, and how to improve them.
- What is lazy loading? How deferring resources speeds up the web
Lazy loading is a performance strategy that defers non-critical resources (images, iframes, JavaScript, CSS) until they are needed. Learn what can be lazy-loaded, the native loading attribute, the Intersection Observer API, and when lazy loading helps or hurts.