๐Ÿ“š Complete Guide

Web Caching

Master browser caching, Service Workers, CDN, and understand server-side caching architecture for blazing-fast web applications.

What is Caching?

Caching is storing a copy of data closer to where it's needed, so you don't fetch it from the slow source every time.

The Impact of Caching
WITHOUT CACHE:
User โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Server โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Database    Every. Single. Time.
      100ms         50ms                 Total: 150ms

WITH CACHE:
User โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Cache    HIT! Return instantly
       5ms            Total: 5ms (30x faster!)
Metric Without Cache With Cache Improvement
Response Time 150-500ms 5-50ms 10-30x faster
Server Load 100% 10-20% 80% reduction
Database Queries Every request Cache misses only 90% reduction

The Caching Layers

There are multiple layers where caching happens. The closer to the user, the faster!

All Caching Layers
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      USER'S DEVICE                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”‚
โ”‚  โ”‚   Memory     โ”‚  โ”‚   Browser    โ”‚  โ”‚   Service    โ”‚           โ”‚
โ”‚  โ”‚   Cache      โ”‚  โ”‚   HTTP       โ”‚  โ”‚   Worker     โ”‚           โ”‚
โ”‚  โ”‚  (fastest)   โ”‚  โ”‚   Cache      โ”‚  โ”‚   Cache      โ”‚           โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           CDN                                   โ”‚
โ”‚            (Edge servers distributed globally)                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    APPLICATION SERVER                           โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                             โ”‚
โ”‚  โ”‚  In-Memory   โ”‚  โ”‚   Redis/     โ”‚                             โ”‚
โ”‚  โ”‚   Cache      โ”‚  โ”‚  Memcached   โ”‚                             โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        DATABASE                                 โ”‚
โ”‚              (Query cache, Buffer pool)                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
๐Ÿ’ก Golden Rule

Cache as close to the user as possible! Browser > CDN > Server > Database

HTTP Cache Headers

The server tells the browser HOW to cache using HTTP response headers:

Header Purpose
Cache-Control Main header - controls all caching behavior
ETag Unique version ID for the resource
Last-Modified When the resource was last changed
Expires Absolute expiry date (legacy, use max-age)
Vary Cache different versions based on request headers

Cache-Control Deep Dive

Cache-Control Anatomy
Cache-Control: max-age=3600, public
               โ”‚              โ”‚
               โ”‚              โ””โ”€โ”€ WHO can cache
               โ””โ”€โ”€ HOW LONG to cache (seconds)

Freshness Directives

HTTP
# Cache for 1 hour
Cache-Control: max-age=3600

# Cache for 1 year (static assets with hash)
Cache-Control: max-age=31536000

# CDN caches longer than browser
Cache-Control: max-age=60, s-maxage=3600
# Browser: 60 seconds, CDN: 1 hour

Cacheability Directives

HTTP
# Anyone can cache (browser, CDN, proxies)
Cache-Control: public, max-age=3600

# Only browser can cache (not CDN) - for user-specific content
Cache-Control: private, max-age=3600

# Don't cache anywhere - sensitive data!
Cache-Control: no-store

# Cache but always revalidate with server first
Cache-Control: no-cache

Advanced Directives

HTTP
# Serve stale while fetching fresh in background (amazing for UX!)
Cache-Control: max-age=60, stale-while-revalidate=3600

# Content NEVER changes (versioned files like app.abc123.js)
Cache-Control: max-age=31536000, immutable

# Serve stale if origin server is down
Cache-Control: max-age=60, stale-if-error=86400

Cache-Control by Content Type

Content Cache-Control Why
Hashed assets (app.abc123.js) public, max-age=31536000, immutable Never changes
Static assets (favicon.ico) public, max-age=86400 Changes rarely
HTML pages no-cache Always check for updates
Public API public, max-age=300, s-maxage=600 Fresh enough
Private API private, max-age=60 User-specific
Sensitive data no-store Never cache!

ETag & Validation

When cache expires, the browser asks: "Is my copy still good?" This is called revalidation.

ETag Validation Flow
FIRST REQUEST (no cache yet):
Browser โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Server
         GET /style.css

Browser โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Server
         200 OK
         ETag: "abc123"
         Cache-Control: max-age=3600
         [CSS content...]

AFTER CACHE EXPIRES (revalidating):
Browser โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Server
         GET /style.css
         If-None-Match: "abc123"  โ† "Is abc123 still valid?"

Server checks: Is "abc123" still current?

IF NOT MODIFIED:
Browser โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Server
         304 Not Modified
         (no body - saves bandwidth!)

IF MODIFIED:
Browser โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Server
         200 OK
         ETag: "xyz789"
         [New CSS content...]
โœ… 304 Not Modified

The 304 response contains no body - just headers. This saves bandwidth while still ensuring fresh content!

Service Workers

Service Workers give you full programmatic control over caching. They sit between your app and the network, intercepting every request.

Service Worker Architecture
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Your App   โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚    Service Worker    โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚   Network    โ”‚
โ”‚              โ”‚         โ”‚                      โ”‚         โ”‚              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ”‚  "I intercept ALL    โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                         โ”‚   requests and       โ”‚
                         โ”‚   decide what to     โ”‚
                         โ”‚   return!"           โ”‚
                         โ”‚                      โ”‚
                         โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
                         โ”‚   โ”‚  Cache API   โ”‚   โ”‚
                         โ”‚   โ”‚  (Storage)   โ”‚   โ”‚
                         โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
                         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key Capabilities

Service Worker Lifecycle

Lifecycle Stages
1. REGISTER
   โ””โ”€โ”€ navigator.serviceWorker.register('/sw.js')
         โ”‚
         โ–ผ
2. INSTALL (first time or when updated)
   โ””โ”€โ”€ Pre-cache static assets
   โ””โ”€โ”€ self.skipWaiting() to activate immediately
         โ”‚
         โ–ผ
3. ACTIVATE
   โ””โ”€โ”€ Clean up old caches
   โ””โ”€โ”€ self.clients.claim() to control pages immediately
         โ”‚
         โ–ผ
4. RUNNING
   โ””โ”€โ”€ Intercepts ALL fetch requests
   โ””โ”€โ”€ You decide: cache, network, or both!

Registration Code

JavaScript
// In your main app JavaScript
if ('serviceWorker' in navigator) {
  window.addEventListener('load', async () => {
    try {
      // Register the service worker file
      const registration = await navigator.serviceWorker.register('/sw.js');
      console.log('SW registered! Scope:', registration.scope);
    } catch (error) {
      console.error('SW registration failed:', error);
    }
  });
}

Service Worker File (sw.js)

JavaScript
const CACHE_NAME = 'my-app-v1';

// Files to cache immediately on install
const PRECACHE_ASSETS = [
  '/',
  '/index.html',
  '/styles/main.css',
  '/scripts/app.js',
  '/offline.html'
];

// INSTALL - Pre-cache static assets
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => cache.addAll(PRECACHE_ASSETS))
      .then(() => self.skipWaiting())
  );
});

// ACTIVATE - Clean up old caches
self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames
          .filter(name => name !== CACHE_NAME)
          .map(name => caches.delete(name))
      );
    }).then(() => self.clients.claim())
  );
});

// FETCH - Intercept requests (implement strategy here)
self.addEventListener('fetch', (event) => {
  event.respondWith(handleRequest(event.request));
});

Caching Strategies

1. Cache First

Check cache โ†’ Return if found โ†’ Otherwise fetch network

Best for: CSS, JS, images, fonts

2. Network First

Try network โ†’ If fails, return from cache

Best for: API data, dynamic content

3. Stale While Revalidate

Return cached immediately โ†’ Update cache in background

Best for: Balance speed & freshness

4. Network Only

Always fetch from network, no caching

Best for: Real-time data, analytics

Cache First Implementation

JavaScript
// Best for: Static assets that rarely change
async function cacheFirst(request) {
  // 1. Check cache first
  const cached = await caches.match(request);
  if (cached) {
    console.log('Cache HIT:', request.url);
    return cached;
  }
  
  // 2. Not in cache - fetch from network
  console.log('Cache MISS, fetching:', request.url);
  const response = await fetch(request);
  
  // 3. Cache for next time
  const cache = await caches.open(CACHE_NAME);
  cache.put(request, response.clone()); // Clone because response is one-time use
  
  return response;
}

Stale While Revalidate Implementation

JavaScript
// Best for: Content where speed matters but freshness is nice
async function staleWhileRevalidate(request) {
  const cache = await caches.open(CACHE_NAME);
  const cached = await caches.match(request);
  
  // Fetch fresh version in background (don't await!)
  const fetchPromise = fetch(request).then(response => {
    cache.put(request, response.clone());
    return response;
  });
  
  // Return cached immediately OR wait for network
  return cached || fetchPromise;
}

Strategy Selection Guide

Content Type Strategy Why
App Shell (HTML) Stale While Revalidate Fast + stays fresh
CSS/JS bundles Cache First Rarely change (use versioned URLs)
Images, Fonts Cache First Large files, rarely change
API - User data Network First Must be fresh
API - Static data Stale While Revalidate Speed + eventual freshness
Real-time data Network Only Can't be stale

Offline Support

Show a custom offline page when the network is unavailable:

JavaScript
async function handleRequest(request) {
  try {
    return await fetch(request);
  } catch (error) {
    // Network failed! Return appropriate fallback
    
    // For HTML pages - show offline page
    if (request.headers.get('Accept').includes('text/html')) {
      return caches.match('/offline.html');
    }
    
    // For images - show placeholder
    if (request.url.match(/\.(png|jpg|jpeg|gif|svg)$/)) {
      return caches.match('/images/offline-placeholder.png');
    }
    
    // For API - return error JSON
    if (request.url.includes('/api/')) {
      return new Response(
        JSON.stringify({ error: 'You are offline' }),
        { 
          status: 503, 
          headers: { 'Content-Type': 'application/json' }
        }
      );
    }
  }
}

CDN Caching

CDNs cache your content at edge servers worldwide, serving users from the nearest location.

CDN Impact
WITHOUT CDN:
User in Tokyo โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Server in New York
                   ~200ms latency           

WITH CDN:
User in Tokyo โ”€โ”€โ”€โ–บ Edge in Tokyo
                    ~10ms
                    
                   Cache HIT! โ†’ Return immediately
                   Cache MISS โ†’ Fetch from origin, cache it

Major CDN Providers

Provider Edge Locations Best For
Cloudflare 300+ Free tier, Workers, DDoS protection
AWS CloudFront 400+ AWS integration, Lambda@Edge
Fastly 70+ Real-time purging, edge compute
Vercel Edge 100+ Next.js apps, serverless

Cache Invalidation Strategies

Versioned URLs

/app.js โ†’ /app.abc123.js

Best for static assets. Cache forever!

Purge API

Call CDN API to invalidate specific URLs

When content updates, purge the cache

Short TTL + SWR

max-age=60, stale-while-revalidate=3600

Auto-updates within 60 seconds

Server-Side Caching (Architecture)

Understanding how backend caching works helps you collaborate with backend teams.

Server Caching Layers
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    APPLICATION SERVER                           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                 โ”‚
โ”‚  1. IN-PROCESS CACHE                                            โ”‚
โ”‚     โ””โ”€โ”€ Stored in server's RAM (~0.01ms)                        โ”‚
โ”‚     โ””โ”€โ”€ NOT shared between servers                              โ”‚
โ”‚     โ””โ”€โ”€ Lost when server restarts                               โ”‚
โ”‚                                                                 โ”‚
โ”‚  2. DISTRIBUTED CACHE (Redis/Memcached)                         โ”‚
โ”‚     โ””โ”€โ”€ Separate cache server (~1ms)                            โ”‚
โ”‚     โ””โ”€โ”€ Shared between all app servers                          โ”‚
โ”‚     โ””โ”€โ”€ Survives server restarts                                โ”‚
โ”‚                                                                 โ”‚
โ”‚  3. DATABASE                                                    โ”‚
โ”‚     โ””โ”€โ”€ Source of truth (~10-50ms)                              โ”‚
โ”‚     โ””โ”€โ”€ Query cache, buffer pool                                โ”‚
โ”‚                                                                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Redis vs Memcached

Feature Redis Memcached
Data types Rich (hash, list, set, sorted set) String only
Persistence Yes (optional disk backup) No (memory only)
Replication Built-in master-slave No built-in
Use case General purpose, sessions, queues Simple caching
๐Ÿ’ก Industry Standard

Most companies use Redis - it has more features and is still blazing fast (100k+ operations/second).

Caching Patterns

Cache-Aside (Lazy Loading)

App checks cache โ†’ Miss โ†’ Fetch DB โ†’ Store in cache

Most common pattern. Simple but first request is slow.

Read-Through

App always asks cache โ†’ Cache handles DB fetch

Cache library manages everything.

Write-Through

Write to cache โ†’ Cache writes to DB โ†’ Confirm

Cache always fresh. Slower writes.

Write-Behind

Write to cache โ†’ Confirm immediately โ†’ Async DB write

Super fast writes. Risk of data loss.
โš ๏ธ Cache Stampede Problem

When a popular cache key expires, thousands of requests hit the database simultaneously! Solutions: locking, early expiration, or stale-while-revalidate.

How Big Companies Cache

๐ŸŽฌ YouTube / Netflix

VIDEO STREAMING STRATEGY:

1. Videos cached at 1000s of edge locations globally
2. Popular videos pushed to edges BEFORE users request
3. Servers placed INSIDE ISP data centers
4. Multiple quality versions cached (360p, 720p, 1080p, 4K)

RESULT: 95%+ of traffic served from edge, <10ms latency

๐Ÿ›’ Amazon / Flipkart

E-COMMERCE CACHING:

โ”œโ”€โ”€ Product catalog: Long TTL, invalidate on update
โ”œโ”€โ”€ Prices: Short TTL (can't show stale prices!)
โ”œโ”€โ”€ Inventory: Real-time or very short TTL
โ”œโ”€โ”€ Static assets: Infinite cache with versioned URLs
โ”œโ”€โ”€ Search results: Cache by query + location
โ””โ”€โ”€ Recommendations: Pre-computed, cached per user segment

CHALLENGE: Personalization makes caching harder

๐Ÿฆ Twitter / X

SOCIAL MEDIA CACHING:

TIMELINE:
โ””โ”€โ”€ Fan-out on write: Pre-compute timelines for users
โ””โ”€โ”€ Celebrity exception: Fan-out on read (too many followers)

TWEETS:
โ””โ”€โ”€ Immutable! Cache forever
โ””โ”€โ”€ Only engagement counts update

TRENDS:
โ””โ”€โ”€ Computed periodically, cached per region

Best Practices Checklist

Frontend Caching

HTTP Headers

Golden Rules

๐Ÿ† Remember These
  • Cache as close to user as possible - Browser > CDN > Server
  • Static = aggressive, Dynamic = careful
  • Have invalidation strategy BEFORE caching
  • When in doubt, shorter TTL is safer
  • Monitor! If cache isn't hit, remove it