Every pattern covered so far assumes a cache that's already been running a while and holds a reasonable working set. A cache that was just deployed, just restarted, or just flushed holds nothing at all — and the gap between those two states is exactly where cache warming lives.
3 min read
A freshly deployed or freshly restarted cache starts completely empty. The very first wave of real traffic it receives is, by definition, a 100% miss rate — every single request falls through to the database, at exactly the moment the system has the least information about what's actually "hot" right now. For a cache fronting a database that was sized assuming most reads are absorbed by the cache, this cold-start traffic spike can itself look a lot like the cache stampede from lesson 4, just caused by a deploy instead of an expiring key.
Cache warming runs a deliberate process — a script, a startup hook, a scheduled job — that populates known-hot keys before real user traffic arrives, so the cache starts in a reasonably "warm" state instead of empty. The most common, practical version: before marking a newly deployed instance healthy and routing traffic to it, run through a list of the most frequently accessed keys (derived from yesterday's access logs, or simply "every product on the homepage") and populate them proactively.
def warm_cache():
top_product_ids = get_most_accessed_ids(limit=500) # from yesterday's access logs
for product_id in top_product_ids:
product = db.query_product(product_id)
cache.set(f"product:{product_id}", product, ttl=300)CI/CD's own zero-downtime-deploy lesson already established the pattern of not routing traffic to a new instance until it passes a readiness check — cache warming is a natural extension of that same idea: a new instance's readiness check can require "cache warming completed" in addition to "process started successfully," so traffic only reaches an instance once its local or attached cache actually holds the hot working set, not the moment the process merely starts running.
Cache warming isn't only a deploy-time concern — a full cache flush (clearing everything, sometimes done deliberately after a major schema change invalidates assumptions baked into existing cache keys) creates the exact same cold-start condition on a cache that's otherwise been running fine for months. Treating a flush as routine, without a warming step afterward, recreates the cold-start spike on a system that otherwise never sees one.
Warming only helps for keys that are predictably hot — a homepage's featured items, yesterday's top sellers. A long-tail of less-predictable keys (a specific user's specific, rarely-viewed order from months ago) will always start cold no matter what's warmed in advance, simply because there's no way to know in advance which of the millions of possible such keys today's traffic will actually touch. Warming is a mitigation for the predictable-hot-key portion of cold-start load, not a way to eliminate cold starts for a cache's entire possible key space.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. What risk does a freshly deployed, completely empty cache create?
2. How does cache warming address this risk?
3. What's the honest limitation of cache warming?
Caching Strategies