Caching Strategies: Redis, HTTP, and CDN Without Serving Rotten Data
Separate cache layers from edge to app; design TTL, invalidation, stampedes, and private user caches correctly.
Ali Mortazavi
Founder, Paradise Code
Cache is not one layer; it is a decision system
CDN for assets and public pages, HTTP cache for intermediaries and browsers, Redis for hot computed or read-heavy app data—each has its own language and failure mode. Treat them as “one cache” and you either ship dangerous stale data or never hit at all.
Ask first: how stale can this be, is it private, and where is the source of truth?
CDN and the edge
Cache fingerprinted assets for a long time; keep HTML shorter or revalidating. For personalized pages, `Cache-Control: private` or an edge bypass is mandatory. A classic failure is caching user A’s response for user B.
Wire edge purge/tag to content publish events. Manual purge alone is not enough outside incidents.
HTTP headers that actually matter
Set `Cache-Control`, `ETag`/`Last-Modified`, and `Vary` deliberately. A mistaken `Vary: Cookie` can nullify or endanger caching. For public read APIs, s-maxage separate from browser max-age is useful.
Do not cache errors for long. A cached 500 page is worse than the outage.
Redis as an application cache
Build keys with domain namespaces and versions: `tenant:42:pricing:v3`. Add jitter to TTLs so expirations do not stampede together. On hot misses, use a lock or singleflight so every request does not crush the origin.
Redis is not a database substitute. Critical data only in cache is a bug waiting for a restart.
Invalidation is harder than set
Two healthy patterns: short TTL with accepted staleness, or event-driven invalidation with precise tags/keys. “Cache forever until we remember to purge” dies in busy teams. Document which events kill which keys.
For lists, versioning the list key is often cheaper than deleting member by member.
Observability and safety
Monitor hit ratio, origin latency, and stale rates. Sudden hit drops usually mean a bad deploy or overly broad invalidation. Keep sensitive data off public CDNs; treat secrets and PII in Redis with strict TTL and access policy.
Good caching shows up as a quiet origin and a fast user—without the team fearing data correctness.
Frequently asked questions
CDN first or Redis first?
CDN for public content and assets. Redis for dynamic/aggregated app data. Often both, in different layers.
Is stale-while-revalidate a good idea?
Excellent for public content. Dangerous for exact inventory or live pricing unless rules are explicit.
How do we reduce stampedes?
TTL jitter, request locking, and warming critical keys before peak traffic.
Is caching GraphQL hard?
Yes, because keying is complex. Persisted queries and caching at a clear data layer usually beat blindly caching full responses.
Insights
Need these ideas implemented in your product?
Paradise Code supports you from consult to full delivery.