logo hsb.horse
← Retour au blog

Blog

Mes notes sur `Cache-Control: max-age=3, must-revalidate`

Une mise au clair du comportement d’une configuration Cache-Control dite de micro-caching. Cet article explique ce que produit réellement la combinaison `max-age=3` + `must-revalidate`, son déroulé dans le temps et des cas d’usage concrets.

Publié:

Je me suis penché sur l’en-tête Cache-Control: max-age=3, must-revalidate, donc je pose ici mes notes avant d’oublier.

Cette configuration signifie : “utiliser le cache pendant seulement trois secondes, puis forcer une validation auprès du serveur d’origine dès qu’il expire”. On appelle généralement cette approche du micro-caching. Elle est souvent utilisée pour protéger le serveur d’origine lors de pics soudains de trafic tout en gardant un contenu proche du temps réel.


Signification de chaque directive

Le plus simple est de séparer les deux directives.

max-age=3

Cela indique aux navigateurs et aux CDN que le contenu est considéré comme frais pendant trois secondes seulement. Pendant cette fenêtre, aucune requête n’est envoyée au serveur d’origine. La réponse est servie immédiatement depuis le cache.

must-revalidate

Une fois ces trois secondes passées, le cache doit revalider auprès du serveur d’origine et ne jamais servir de contenu périmé sans validation explicite.

Sans cette directive, certains caches ou certaines configurations peuvent choisir de renvoyer du contenu périmé quand l’origine est indisponible. must-revalidate interdit clairement ce comportement.


Déroulé temporel

Le plus parlant est de simuler ce qui se passe quand un utilisateur charge la page.

MomentAction de l’utilisateurComportementCode HTTP
Première requêteAccès à la pageRécupération depuis l’origine puis affichage200 OK
Immédiatement jusqu’à 3 secondesRechargement / navigationAucune requête à l’origine. Le navigateur ou le CDN sert la réponse en cache200 (from cache)
Après 3 secondesRechargement / navigationLe cache est considéré comme expiré. Le navigateur envoie une requête conditionnelleRequête réseau
→ Pas de changementLe serveur répond qu’il n’y a pas de modification. Le cache existant redevient valide pour 3 secondes. Le corps n’est pas retéléchargé304 Not Modified
→ Changement détectéLe serveur renvoie la nouvelle version200 OK

Le point important est le cas 304 Not Modified après expiration. Comme le corps du contenu n’est pas retéléchargé, on réduit à la fois la bande passante et la latence.


Avantages

Ce header est particulièrement pertinent quand la fraîcheur est importante mais que le trafic est très élevé. Trois bénéfices sont à retenir.

Réduction importante de la charge sur l’origine

Imaginez un site qui reçoit 1 000 requêtes par seconde. Avec max-age=3, surtout derrière un CDN, la plupart des requêtes sont absorbées par le cache et l’origine n’a besoin de traiter qu’un nombre bien plus faible de validations.

Même trois secondes de cache peuvent faire une énorme différence à fort trafic.

Mise à jour presque en temps réel

Les nouvelles données deviennent visibles au plus tard au bout de trois secondes. Ce n’est pas du temps réel strict, mais c’est souvent un compromis acceptable.

Réduction du risque d’afficher des données périmées

Grâce à must-revalidate, le client ne peut pas continuer à servir silencieusement de vieilles données après expiration. C’est important quand l’exactitude de l’information compte.


Cas d’usage concrets

J’ai essayé de lister les situations où ce réglage me semble adapté.

Cas adaptés

  • Page d’accueil ou listings d’un site d’actualités : les nouveaux articles doivent apparaître vite, mais quelques secondes de délai restent acceptables, avec des pics de trafic fréquents
  • Affichage des stocks sur un site e-commerce : quelques secondes de retard sont tolérables, mais il ne faut pas afficher un produit épuisé comme disponible. must-revalidate aide à éviter ce problème
  • Landing pages d’événements ou de campagnes : juste après publication, le trafic peut exploser via les réseaux sociaux. Le micro-caching absorbe la première vague tout en gardant des mises à jour rapides
  • Écrans de synthèse dans un dashboard : moins sensibles qu’un graphique en temps réel, mais ils doivent refléter des KPI récents. Si le polling est de trois secondes ou plus, ce réglage peut bien fonctionner
  • Réponses d’API de type liste : en ajoutant ce header, on peut laisser le CDN mettre en cache la réponse et réduire la charge sur l’origine

Cas peu adaptés

  • Assets statiques comme CSS, JS ou images : ils changent peu souvent. Une stratégie avec hash de fichier et max-age=31536000,immutable est généralement meilleure
  • Pages détail d’articles de blog : elles sont rarement modifiées souvent après publication, donc un max-age beaucoup plus long convient mieux
  • Chat temps réel ou WebSocket : le cache HTTP ne s’applique pas vraiment ici, et même trois secondes de retard sont déjà trop
  • Contenu spécifique à l’utilisateur : pour une page de compte par exemple, un cache partagé au niveau CDN n’est souvent pas approprié. Il faut envisager des directives comme private

Points d’attention

Il y a aussi quelques compromis faciles à sous-estimer.

Une requête revient tous les trois secondes après expiration

Après chaque fenêtre de trois secondes, une requête conditionnelle partira forcément. Par rapport à un max-age plus long, la latence réseau pèse donc davantage. Il faut y penser côté UX sur des connexions lentes.

Comportement hors ligne

À cause de must-revalidate, si le réseau est coupé ou que l’origine tombe, le client risque d’afficher une erreur même si un cache expiré existe encore. Autrement dit, cette politique dit : “si je ne peux pas vérifier la fraîcheur, je préfère échouer plutôt que servir de l’ancien”.

Si c’est trop strict, il vaut mieux envisager des directives comme stale-while-revalidate ou stale-if-error.


Résumé

Cache-Control: max-age=3, must-revalidate est un réglage assez agressif pour les situations où la fraîcheur est critique mais où l’on ne veut pas mettre l’origine à genoux.

Le terme “micro-caching” sonne plus impressionnant que la réalité. En pratique, il s’agit juste de mettre en cache pendant quelques secondes. Sous forte charge, ces quelques secondes peuvent pourtant avoir un effet énorme.

Avant de l’utiliser, il faut vérifier que la cible correspond vraiment à ce schéma. Si on l’applique à des assets statiques ou à des pages rarement mises à jour, on ne fait qu’ajouter des requêtes de revalidation inutiles.