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.
| Moment | Action de l’utilisateur | Comportement | Code HTTP |
|---|---|---|---|
| Première requête | Accès à la page | Récupération depuis l’origine puis affichage | 200 OK |
| Immédiatement jusqu’à 3 secondes | Rechargement / navigation | Aucune requête à l’origine. Le navigateur ou le CDN sert la réponse en cache | 200 (from cache) |
| Après 3 secondes | Rechargement / navigation | Le cache est considéré comme expiré. Le navigateur envoie une requête conditionnelle | Requête réseau |
| → Pas de changement | — | Le 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 version | 200 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-revalidateaide à é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,immutableest généralement meilleure - Pages détail d’articles de blog : elles sont rarement modifiées souvent après publication, donc un
max-agebeaucoup 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.
hsb.horse