WhollySoftware
Back to blogWeb

Caching Strategies for Content-Heavy Sites

Wholly Software TeamJune 16, 20257 min read
Caching Strategies for Content-Heavy Sites

A digital publishing client's origin server would intermittently return 500 errors during traffic spikes from viral articles, despite the server having plenty of CPU and memory headroom according to their monitoring. The actual problem was a cache invalidation strategy that purged the entire CDN cache on every single content update anywhere on the site, including minor typo fixes to unrelated archived articles, which meant a spike in editorial activity during a traffic surge could thundering-herd the origin.

We moved to path-based, surgical invalidation — publishing or editing an article invalidates only that article's URL and the specific listing pages that reference it (homepage, its category page), rather than a blanket purge. This required tracking which cached pages referenced which content IDs, which we handled with a small invalidation-mapping table updated whenever a page was generated, rather than trying to guess dependencies at purge time.

For the CDN layer itself, we set differentiated cache TTLs by content type rather than one global value: article pages got a 5-minute edge TTL with stale-while-revalidate for up to an hour, so a burst of traffic during revalidation still got served instantly from a slightly stale cache instead of waiting on origin. Static assets (images, fonts, compiled JS/CSS) got a one-year TTL with content-hashed filenames, so cache invalidation for those was never a manual operation at all — a new build just generated new filenames.

We also added a Redis layer between the application and the database for expensive, frequently-repeated queries — most notably a 'related articles' computation that was running a non-trivial query on every single article page view. Caching that query's result per article with a 15-minute TTL cut database load during peak traffic by roughly 60%, since related articles don't need to be recalculated on every request.

The stale-while-revalidate pattern was the change that mattered most during actual traffic spikes: instead of a cache miss triggering a synchronous origin fetch that every concurrent request had to wait on, one request revalidates in the background while everyone else gets the stale-but-valid cached version. That single pattern is what stopped the thundering herd problem that had been causing the original 500 errors.

Since these changes went live, the client has had two viral traffic spikes exceeding 15x normal load with zero origin errors, and origin request volume during normal traffic dropped by about 70% overall.

CachingCDNRedisWeb Performance
Caching Strategies for Content-Heavy Sites — Wholly Software