Technology

Caching Strategies: Redis, CDN, and Edge Computing

Cache at every layer. HTTP caching, Redis, CDNs, and edge computing for sub-100ms response times.

All articles
TechnologyNexaEx TeamMarch 1, 2026 8 min read
Caching Strategies: Redis, CDN, and Edge Computing

The Caching Imperative

Users hate slow websites. Slow = lost conversions. Every 100ms latency costs 1% of revenue (real data from Amazon, Google).

Caching is the primary lever for speed. Cache data, cache computations, cache responses. Layer caches reduce latency and load.

Cache Layers (Outside to Inside)

Layer 1: Browser cache

  • User's browser caches static assets (CSS, JS, images).
  • Set via Cache-Control headers (e.g., "max-age=31536000" = 1 year).
  • Free, instant.

Layer 2: CDN cache

  • Global network of servers. Content cached near users.
  • User in Mumbai gets content from Mumbai edge server, not US origin.
  • 50-100x faster than fetching from origin.
  • Cost: $0.01-0.10 per GB (or fixed monthly, $20+).

Layer 3: Application cache

  • Redis or Memcached. Cache expensive computations or database queries.
  • Reduces database load dramatically.
  • Cost: $0.10-1.00 per GB per month (depends on service).

Layer 4: Database cache

  • Row cache, query result cache.
  • Some databases (PostgreSQL) have built-in caching.
  • Minimal additional cost.

HTTP Caching Headers

Instruct browsers and CDNs how to cache content.

Cache-Control: public, max-age=3600
  ^ Cache-Control header
    ^ public = CDNs can cache
      ^ max-age=3600 = cache for 3600 seconds (1 hour)

Strategies:

  • Static assets (CSS, JS): Cache-Control: public, max-age=31536000 (1 year)

    • Add hash to filename: app.a1b2c3.js
    • When code changes, filename changes, browser fetches new version
    • Old version stays in cache forever (doesn't waste space)
  • HTML pages: Cache-Control: public, max-age=300 (5 minutes)

    • Short cache so updates are visible quickly
    • Or use: Cache-Control: no-cache + ETags for conditional requests
  • API responses: Cache-Control: private, max-age=60 (1 minute)

    • private = don't cache at CDN, only browser
    • Or use Redis for server-side caching

Redis for Application Caching

Redis is a fast in-memory database. Cache expensive queries and computations.

import redis
from functools import wraps

cache = redis.Redis(host='localhost', port=6379, db=0)

def get_user_profile(user_id):
  # Try cache first
  cached = cache.get(f'user:{user_id}')
  if cached:
    return json.loads(cached)

  # Cache miss, query database
  user = database.query(f'SELECT * FROM users WHERE id = {user_id}')

  # Save to cache for 1 hour
  cache.setex(f'user:{user_id}', 3600, json.dumps(user))

  return user

Cache invalidation: When data changes, invalidate cache.

def update_user_profile(user_id, data):
  database.update(f'UPDATE users SET ... WHERE id = {user_id}')
  cache.delete(f'user:{user_id}')  # Invalidate cache

Cache stampede: If cache expires and 1000 requests hit simultaneously, they all query the database.

Prevent with:

  • Longer cache TTL (time-to-live)
  • Probabilistic early expiration (recompute before expiration)
  • Mutual exclusion (only one thread recomputes, others wait)

CDN for Global Performance

CDNs cache content near users. Cloudflare, Fastly, AWS CloudFront, etc.

How it works:

  1. User in India requests myapp.com/logo.png
  2. CDN edge server in India checks cache
  3. Cache hit: serve instantly from India (2ms latency)
  4. Cache miss: fetch from origin (US), serve to user, cache for future

Cost: $0.01-0.10 per GB (outbound data). For 1TB/month, $10-100. Expensive at scale, but ROI is high (performance = conversions).

Cache control at CDN:

Cache-Control: public, max-age=3600, s-maxage=86400
  ^ s-maxage = CDN cache TTL (1 day)
  ^ max-age = browser cache TTL (1 hour)

Tell CDN to cache for 1 day, browser for 1 hour.

Edge Computing: Compute at the Edge

Cloudflare Workers, AWS Lambda@Edge: run code at edge servers.

Use for:

  • Rewrite URLs based on user location
  • A/B testing (serve variant based on cookie)
  • Authentication (check JWT before routing)
  • Rate limiting
// Cloudflare Worker
export default {
  fetch: (request) => {
    if (request.headers.get('X-Test-User')) {
      return fetch('https://variant-b.myapp.com' + request.url.pathname);
    }
    return fetch('https://variant-a.myapp.com' + request.url.pathname);
  }
}

Reduces latency by computing near users instead of centralizing.

Cache Invalidation Strategies

"There are only two hard things in Computer Science: cache invalidation and naming things." — Phil Karlton

Time-based (TTL):

  • Set expiration: cache expires after N seconds
  • Simple, but stale data risk

Event-based (active invalidation):

  • When data changes, explicitly invalidate cache
  • Fast, but requires coordination

Hybrid:

  • Set TTL to 1 hour
  • Invalidate immediately when data changes
  • If invalidation fails, TTL is fallback

Example:

def publish_blog_post(post_id):
  database.insert(post)

  # Invalidate cache
  try:
    cache.delete(f'post:{post_id}')
  except:
    pass  # If cache is down, TTL will clean up

Caching Checklist

  • Set HTTP cache headers (Cache-Control, ETag)
  • Use hashed filenames for static assets
  • Deploy CDN for static content
  • Implement Redis for application caching
  • Cache frequently accessed queries
  • Set reasonable TTLs (1 minute to 1 hour for most data)
  • Implement active cache invalidation
  • Monitor cache hit rate (target: >80%)
  • Monitor CDN performance (latency, hit rate)
  • Test cache behavior (verify correctness)

Frequently asked questions

What cache hit rate should we target?

80%+ for most applications. If hit rate is <50%, your cache is ineffective. Adjust TTLs or cache different data. Monitor with metrics: (cache_hits) / (cache_hits + cache_misses).

Should we cache database connections or queries?

Both. Connection pooling caches connections (reduces overhead of creating new connections). Query caching (Redis) caches results. Database-level caching (PostgreSQL buffer pool) is built-in. Use all three layers.

What happens if cached data is wrong?

Serve stale data until cache expires (or is invalidated). Users might see outdated information for a few seconds/minutes. This is acceptable for most data. For critical data (account balance, permission), use shorter TTLs or invalidate immediately.

Let's build your next idea

One conversation to scope the work, meet the team, and get a proposal — usually within two business days.