{
    "slug": "cache_stampede",
    "term": "Cache Stampede / Thundering Herd",
    "category": "performance",
    "difficulty": "advanced",
    "short": "When a cached item expires, multiple simultaneous requests all miss the cache and hit the database concurrently, overwhelming it.",
    "long": "A cache stampede occurs when a popular cached item expires and many concurrent requests all find a cache miss simultaneously — each generates the same expensive query, flooding the database. Solutions include: mutex/lock-based regeneration (only one process rebuilds, others wait), probabilistic early expiry (start rebuilding before TTL expires with a small probability), stale-while-revalidate (serve stale data while regenerating in the background), and cache warming on deploy. In PHP with Redis, implement a lock with SET key value NX EX seconds — the first process acquires it and rebuilds, others serve stale or wait.",
    "aliases": [
        "thundering herd",
        "dog pile effect",
        "cache stampede problem"
    ],
    "tags": [
        "performance",
        "caching",
        "concurrency"
    ],
    "misconception": "Cache stampedes only affect very high-traffic sites. Any site with concurrent requests and a cache key that expires can trigger a stampede — even moderate traffic causes multiple simultaneous cache misses that hammer the database. Probabilistic early expiry or locking prevents it.",
    "why_it_matters": "Cache stampedes occur when many requests simultaneously discover an expired cache entry and all attempt to regenerate it concurrently — the backend receives a spike of expensive queries at once.",
    "common_mistakes": [
        "No mutex or locking around cache miss regeneration — all concurrent requests hit the backend.",
        "Setting all cache entries to expire at the same time — use TTL jitter to spread expiry.",
        "Not using probabilistic early expiry — start regenerating before expiry to avoid a cliff-edge miss.",
        "Short TTLs on expensive-to-compute values — frequent expiry increases stampede probability."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "caching",
        "redis_patterns",
        "n_plus_one",
        "database_indexing"
    ],
    "prerequisites": [
        "caching",
        "redis_patterns",
        "mutex_semaphore"
    ],
    "refs": [
        "https://en.wikipedia.org/wiki/Cache_stampede"
    ],
    "bad_code": "// On cache miss, 100 simultaneous requests all hit the DB\n$value = $cache->get('popular_data');\nif ($value === null) {\n    $value = $this->db->expensiveQuery(); // thundering herd\n    $cache->set('popular_data', $value, 300);\n}",
    "good_code": "// Option 1 — Mutex/lock (only one request recomputes)\n$lock = $this->locks->acquire('popular_data', ttl: 10);\nif ($lock) {\n    try {\n        $value = $this->db->expensiveQuery();\n        $cache->set('popular_data', $value, 300);\n    } finally { $lock->release(); }\n} else {\n    // Other requests wait briefly then read from cache\n    sleep(1);\n    $value = $cache->get('popular_data');\n}\n\n// Option 2 — Probabilistic early recomputation (no lock needed)\n// Recompute before expiry with increasing probability as TTL decreases",
    "quick_fix": "Use probabilistic early expiry (recalculate before TTL expires) or a mutex lock (Redis SET NX) to prevent multiple processes rebuilding the same cache simultaneously",
    "severity": "high",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/cache_stampede",
        "html_url": "https://codeclaritylab.com/glossary/cache_stampede",
        "json_url": "https://codeclaritylab.com/glossary/cache_stampede.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Cache Stampede / Thundering Herd](https://codeclaritylab.com/glossary/cache_stampede) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/cache_stampede"
            }
        }
    }
}