Cache Stampede (ruée sur le cache)

Architecture 🔴 Senior

Définition

Incident où une clé très demandée expire et où des centaines de requêtes simultanées ratent le cache en même temps et recalculent toutes la même valeur, écrasant la base. Parades : verrou ou « single flight » (une seule recalcule, les autres attendent), servir la valeur périmée pendant le recalcul (stale-while-revalidate), et l'expiration anticipée probabiliste XFetch (article VLDB 2015) où chaque lecteur a une probabilité croissante de rafraîchir avant l'échéance, ce qui lisse les recalculs.

Analogie

La sonnerie de fin de cours : si toute l'école se rue sur la même cantine à la même seconde, la file explose ; faire sortir les classes avec quelques minutes d'écart règle le problème.

Exemple de code

// XFetch : rafraîchir « un peu avant » avec une probabilité croissante
const BETA = 1.0;
async function getWithXFetch(key, ttlSec, compute) {
  const hit = await cache.get(key);   // { value, expiry, delta }
  const now = Date.now() / 1000;
  const mustRefresh =
    !hit || now - hit.delta * BETA * Math.log(Math.random()) >= hit.expiry;
  if (!mustRefresh) return hit.value;

  const t0 = Date.now() / 1000;
  const value = await compute();          // recalcul coûteux
  const delta = Date.now() / 1000 - t0;   // durée du recalcul
  await cache.set(key, { value, delta, expiry: now + ttlSec });
  return value;
}

Cas d'usage

Page d'accueil, top produits, configuration globale : toute clé chaude dont le recalcul est coûteux et l'expiration synchronisée.

Anti-pattern

Mettre le même TTL rond (3600 s) sur mille clés créées au même déploiement : elles expirent toutes ensemble et provoquent la ruée.
#architecture#cache#performance

Fiche mise à jour le 2026-09-27

← → au clavier pour passer d'une fiche à l'autre