Stackvora.tech

Caching Layers Demystified

The caching layers in a modern web app — CDN, HTTP, in-process, distributed — and how to pick correctly.

Caching is a stack, not a single knob. The right place to cache depends on what you are caching and who can invalidate it.

The layers, from client to database

  1. Browser cache — controlled by Cache-Control and ETag headers.
  2. CDN — CloudFront, Cloudflare, Fastly. Global edge.
  3. Reverse proxy — nginx, Varnish, HAProxy in front of your origin.
  4. Application in-process — LRU inside the Node/Go/Python process.
  5. Distributed cache — Redis, Memcached, Dragonfly.
  6. Database — Postgres shared_buffers, MySQL query cache, materialized views.

What to cache where

DataBest layerReason
Static assets (JS, CSS, images)CDN + long Cache-ControlContent-hashed URLs — cache forever.
Public HTML pagesCDN with short TTL + stale-while-revalidateFresh enough, blazing fast.
Per-user API responsesRedis + short TTLSkip re-computing personalized data every request.
Expensive DB queriesIn-process + Redis (two levels)Hit in-process first; miss → Redis; miss → DB.
Session dataRedis with expirationFast, shared across app instances.

The invalidation problem

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

Practical patterns that work:

  • Short TTLs — for most data, 30–120 seconds is invisible to users and eliminates 90% of invalidation bugs.
  • Explicit invalidate on write — for user-visible data, delete/purge the cache key in the same code path as the write.
  • Cache tags — group related keys so you can purge a set with one call (Cloudflare supports this natively).

What NOT to cache

  • Authentication decisions.
  • Data with regulatory freshness rules (banking balances, medical records).
  • Anything you cannot invalidate atomically when it changes.

Back to the knowledge base · Ask the AI assistant