\"Just cache it in Redis\" is where many designs stop and where many outages begin. A hot key expires, thousands of concurrent requests miss together, and PostgreSQL absorbs a sudden identical query storm. That failure mode is a Redis cache stampede—also called a thundering herd. This article walks through cache-aside, TTL policy, background refresh, singleflight locks, jitter and stale-while-revalidate with Laravel-focused examples.
Hits, Misses and Cache-Aside
A hit returns the Redis value without touching the database. A miss loads the origin, stores the result and returns it. Cache-aside keeps PostgreSQL as source of truth while Redis accelerates repeated reads:
Cache::remember("product:{$id}", 300, fn () => Product::findOrFail($id));Memory lookups are often dramatically cheaper than SQL, but treat \"100× faster\" as storytelling unless you measured your path—serialization, network and query complexity all matter. For product-level guidance see when you should and shouldn't use Redis caching. If the cache tier itself is down, start with Redis connection refused.
TTL Is a Business Decision
Thirty seconds means fresher data and more regenerations. One hour means fewer origin reads and older values. Pair TTL with explicit invalidation on writes for objects editors change often. Display caches can be wrong for a few minutes; booking availability and payment state cannot. Authoritative checks belong on the primary database at commit time even when the UI read a cached card moments earlier.
Anatomy of a Stampede
Key product:1001 expires at noon. Ten thousand clients request it in the same second. Without coordination, each observes a miss and runs the loader. Connection pools fill, CPU spikes and unrelated queries slow down. Application-level N+1 patterns multiply the damage—see N+1 query problems.
Background Refresh
For known celebrities in your keyspace, refresh on a schedule before expiry so interactive traffic rarely rebuilds from cold. Keep a fallback miss path when the refresher fails; never assume the cron always ran.
Singleflight / Request Coalescing
Only one caller should rebuild a key while peers wait. Distributed locks on shared Redis coordinate multiple app servers:
$lock = Cache::lock("refresh:product:{$id}", 10);
if ($lock->get()) {
try {
$value = Product::findOrFail($id);
Cache::put("product:{$id}", $value, 300);
} finally {
$lock->release();
}
}Cache::remember() is excellent DX but does not guarantee cross-node singleflight for every concurrent miss. Handle lock loss, timeouts and empty results deliberately.
Jittered TTLs
Identical TTLs written in a burst expire in a burst. Add randomness:
$ttl = 300 + random_int(0, 60);
Cache::put($key, $value, $ttl);Jitter spreads many keys. One ultra-hot key still needs locking, proactive refresh or stale-while-revalidate.
Stale-While-Revalidate
Cache::flexible('project:statistics', [300, 600], fn () => Project::stats());Serve fresh data inside the first window, optionally serve stale data while refresh is deferred in the second window, and force regeneration afterward. Ideal for dashboards and public catalogs; inappropriate for money movement.

Metrics
- Hit and miss ratios by key prefix
- Redis memory, evictions and CPU
- Regeneration latency for hot keys
- Database QPS aligned to expiry cliffs
- Lock contention and wait timeouts
FAQs
What is a redis cache stampede?
A burst of identical origin loads caused by many clients missing the same cache entry at once after expiry or eviction.
Does remember() prevent stampedes?
It implements cache-aside with TTL. Multi-server stampedes usually need locks, jitter or flexible freshness on top.
Interview answer outline?
Define cache-aside, name the stampede, then offer coalescing, jitter, background refresh and stale-while-revalidate with consistency caveats.
Putting It Into Practice
Teams that succeed treat architecture as a sequence of bets backed by measurements. They keep a short written playbook: which metrics page to open during an incident, which cache keys are sacred, which database roles exist for read traffic, and which deploy strategy applies to API versus workers. They load-test the paths that matter—login, search, checkout—before marketing campaigns, and they refuse to "just shard" because a dashboard looked busy for an hour.
Documentation should capture the failure modes you already paid for: a session store that was local, a migration that dropped a column too early, a cache TTL that stampeded PostgreSQL, a retry loop without jitter. New engineers should be able to replay those lessons without repeating the outage. Pair this article with the sibling write-ups in this batch on zero-downtime releases, cache stampede control, Bloom filters, exponential backoff and read replicas versus sharding so the whole toolkit sits in one place.
Finally, remember that customer interest keywords—faster checkout, fewer timeouts, safer deploys, quicker username checks—map directly to these engineering choices. Marketing language and system design meet where latency and reliability become features users can feel.
Operational Checklist Teams Actually Use
Write the runbook while the system is healthy. Name the dashboards that show latency, error rate, saturation and dependency health. Record which alerts page which engineers, and which feature flags disable expensive paths when a dependency falters. After every incident, add one concrete prevention item—an index, a probe, a lock, a backoff—and assign an owner with a date.
Load-test the golden journeys before campaigns: authentication, search, write paths and payment or booking confirmation. Synthetic traffic that only hits health endpoints will not reveal stampede, lock or migration bugs. Prefer realistic payloads and concurrency patterns captured from production anonymized traces.
Keep environment parity honest. Staging should exercise the same session store, cache backend, queue driver and migration path as production, even at smaller scale. Many \"works on my machine\" deploy failures are really \"staging used the file session driver.\" Align configuration templates and fail CI when critical env keys diverge.
Security and reliability meet in the same releases. Rotate credentials when workers or containers may have logged them, limit debug endpoints and ensure readiness checks never expose secrets. Customer-facing promises—fast pages, safe checkout, always-on apps—depend on these unglamorous controls as much as on clever algorithms.
How This Fits Customer-Facing Messaging
Engineering topics translate cleanly into buyer language when you stay specific. Faster page loads come from caching and query work. Fewer failed checkouts come from idempotent retries and primary reads after writes. Continuous releases without maintenance banners come from zero-downtime deployment discipline. Instant \"username taken\" feedback comes from probabilistic filters backed by real constraints. Use those outcomes in titles and meta descriptions so searchers who care about reliability find the technical depth behind the promise.
Operational Checklist Teams Actually Use
Write the runbook while the system is healthy. Name the dashboards that show latency, error rate, saturation and dependency health. Record which alerts page which engineers, and which feature flags disable expensive paths when a dependency falters. After every incident, add one concrete prevention item—an index, a probe, a lock, a backoff—and assign an owner with a date.
Load-test the golden journeys before campaigns: authentication, search, write paths and payment or booking confirmation. Synthetic traffic that only hits health endpoints will not reveal stampede, lock or migration bugs. Prefer realistic payloads and concurrency patterns captured from production anonymized traces.
Keep environment parity honest. Staging should exercise the same session store, cache backend, queue driver and migration path as production, even at smaller scale. Many \"works on my machine\" deploy failures are really \"staging used the file session driver.\" Align configuration templates and fail CI when critical env keys diverge.
Security and reliability meet in the same releases. Rotate credentials when workers or containers may have logged them, limit debug endpoints and ensure readiness checks never expose secrets. Customer-facing promises—fast pages, safe checkout, always-on apps—depend on these unglamorous controls as much as on clever algorithms.
How This Fits Customer-Facing Messaging
Engineering topics translate cleanly into buyer language when you stay specific. Faster page loads come from caching and query work. Fewer failed checkouts come from idempotent retries and primary reads after writes. Continuous releases without maintenance banners come from zero-downtime deployment discipline. Instant \"username taken\" feedback comes from probabilistic filters backed by real constraints. Use those outcomes in titles and meta descriptions so searchers who care about reliability find the technical depth behind the promise.




Comments
Join the discussion. Replies load on demand, up to 5 levels.
0 threads
No comments yet
Be the first to start the conversation.