Library · Performance
Caching strategy, layer by layer.
The problem
Around the two-hundredth customer, the same queries run thousands of times a minute, p95 latency climbs, and the database becomes the most expensive line on the cloud bill. Caching is how systems stay fast and affordable - and it is also the source of the industry’s favourite joke about hard things, because a stale cache is a bug users can see.
The architecture
Each layer answers what it can so the next never hears about it. Browser: hashed, immutable assets cached for a year (this site ships its frames and bundles exactly that way - see the numbers). Edge/CDN: public, personalisation-free responses. Redis: hot application data - rendered fragments, expensive aggregates, session and rate-limit state - via cache-aside: read the cache, miss to Postgres, write back with a TTL. PostgreSQL: the truth, reached only when it must be.
The rules that keep it sane
- Every key has a TTL. Explicit invalidation is an optimisation on top - never the only line of defence. A forgotten key must die of old age, not live forever.
- Stampede protection. When a hot key expires, one request rebuilds it while others serve the stale value (stale-while-revalidate) or wait on a short lock - otherwise expiry becomes a self-inflicted outage.
- Never cache authorization. Permission checks and anything money-shaped read the source of truth. A stale product name is cosmetic; a stale permission is an incident.
- Measure hit rates. A cache nobody measures quietly becomes a cache that serves nothing but risk.
Advantages & disadvantages
Advantages: order-of-magnitude latency wins on hot paths; database load and cost drop; graceful degradation under spikes. Disadvantages: staleness becomes a product decision you must make explicitly per data type; invalidation logic is real complexity that must be tested; a cache can mask a slow query until the day the cache is cold - keep the underlying queries honest too.
Technology selection
Redis, for reasons in the ADR: sub-millisecond reads, data structures that match real needs (counters, sorted sets, TTLs), and one operationally boring service covering caching, sessions, rate limits and queues.
Related: Background jobs & queues · Multi-tenant SaaS · Benchmarks · Cloud Engineering