Deux caches, un seul bouton de purge

Il y a au moins deux caches entre votre serveur et l'écran du visiteur, et le bouton de purge du dashboard Cloudflare n'en atteint qu'un seul.

  • Le cache edge réside dans les datacenters Cloudflare. Vous le contrôlez entièrement : vous pouvez le purger, fixer sa durée de vie avec un Edge TTL, et observer ses décisions dans l'en-tête de réponse cf-cache-status.
  • Le cache navigateur réside sur la machine de chaque visiteur. Sa durée de vie a été fixée par l'en-tête Cache-Control envoyé au moment du premier téléchargement, et une fois cet en-tête parti, vous ne pouvez plus le reprendre. La documentation Cloudflare est explicite sur ce point : purger le cache Cloudflare n'affecte pas les ressources stockées par le navigateur d'un visiteur.

Cette seule distinction explique la grande majorité des situations « j'ai purgé et rien n'a changé ». Si vous avez servi hier une feuille de style avec Cache-Control: public, max-age=31536000, votre navigateur continuera d'utiliser sa copie locale pendant un an, quel que soit le nombre de purges effectuées à l'edge. La purge a fonctionné, mais la copie que vous consultez vient du navigateur, pas de l'edge.

Deux conséquences pratiques. D'abord, vérifiez toujours une purge avec un outil qui n'a pas de cache propre, curl étant le candidat évident, avant de modifier quoi que ce soit d'autre. Ensuite, restez prudent sur le Browser TTL : la valeur par défaut du cache navigateur chez Cloudflare est de quatre heures. Avec cette durée, un navigateur peut encore afficher l'ancienne version plusieurs heures après la mise en ligne.

Ce que fait réellement une purge, et laquelle choisir

Cloudflare propose cinq méthodes de purge, et depuis avril 2025 elles sont toutes disponibles sur tous les plans, Free compris. Seuls les quotas diffèrent d'un plan à l'autre.

  • Purge par URL unique : la méthode recommandée par Cloudflare. Elle supprime un objet, et la requête suivante sur cette URL renvoie MISS. Jusqu'à 100 URL par requête sur les plans Free, Pro et Business.
  • Purge par préfixe : vide tout ce qui se trouve sous un chemin, par exemple exemple.com/blog. Elle ignore les query strings, ce qui est précisément ce qui lui permet de rattraper les purges par URL qui échouent. Maximum 100 préfixes par requête, et pas plus de 31 séparateurs de chemin par préfixe.
  • Purge par tag : s'appuie sur un en-tête Cache-Tag que votre origine ajoute aux réponses. L'en-tête agrégé ne peut pas dépasser 16 Ko, soit environ un millier de tags. C'est le bon outil pour un CMS qui doit invalider un article présent sur des dizaines d'URL.
  • Purge par hostname : vide tout ce qui est servi sous un hôte donné, jusqu'à 100 hostnames par requête.
  • Purge Everything : vide la zone entière. Cloudflare déconseille explicitement d'en faire une habitude, car toutes les requêtes suivantes repartent d'un coup vers votre origine. Sur un site à fort trafic, c'est un pic de charge que vous vous infligez vous-même, et les symptômes peuvent ressembler à des erreurs 521, 522 ou 524 intermittentes vers l'origine.

Les quotas méritent d'être connus avant de conclure qu'une purge « n'est pas partie ». Pour hostname, tag, préfixe et Purge Everything, les limites sont par compte : cinq requêtes par minute sur Free, cinq par seconde sur Pro, dix par seconde sur Business, cinquante par seconde sur Enterprise. Un script de déploiement qui purge en boucle sur un plan Free atteindra ce plafond en silence.

Pourquoi la purge par URL rate si souvent sa cible

Une purge par URL ne vise pas un fichier, elle vise une clé de cache. La clé de cache par défaut, c'est l'URL complète : le protocole, l'hôte, et l'URI query string comprise. Tout le reste en découle.

  • La query string compte. Purger https://exemple.com/style.css ne purge pas https://exemple.com/style.css?v=3. Ce sont deux objets distincts à l'edge. Les paramètres de cache-busting, technique employée justement pour forcer les mises à jour, sont aussi ce qui fait rater la purge par URL.
  • Le protocole et l'hôte doivent correspondre exactement. Une purge soumise pour http:// ne touche pas l'objet https://, et exemple.com n'est pas www.exemple.com.
  • Le chemin est sensible à la casse, l'hôte ne l'est pas. Cloudflare met la partie hôte en minuscules conformément aux RFC, mais /BonjourSalut et /bonjoursalut restent deux clés différentes.
  • Une clé de cache personnalisée casse la purge depuis le dashboard. Si une cache rule construit la clé à partir d'en-têtes ou de cookies, le dashboard ne peut pas transmettre ces valeurs et la purge ne trouve rien à supprimer. Passez par l'API en incluant les valeurs d'en-têtes et de cookies concernées, ou repliez-vous sur la purge par préfixe, par tag ou totale. Les clés personnalisées qui ne modifient que le traitement de la query string continuent en général de fonctionner depuis le dashboard.
  • Une cache rule limitée à GET empêche la purge. Les requêtes de purge n'arrivent pas en GET. Une règle écrite (http.host eq "exemple.com" and http.request.method eq "GET") ne correspondra pas pendant une purge. Le correctif donné par Cloudflare consiste à élargir l'expression : (http.request.method eq "GET" or http.request.method eq "PURGE"). Ce piège est invisible depuis le dashboard et coûte des heures quand on l'ignore.
  • Les transform rules inversent l'URL à utiliser. Si une transform rule réécrit une partie du chemin, une purge par URL unique doit employer l'URL d'origine vue par l'utilisateur, alors qu'une purge par préfixe doit employer l'URL après transformation. Inverser les deux produit une purge qui s'annonce réussie et ne change rien.

Le délai réel d'une purge

Bien plus court qu'on ne le suppose. Cloudflare annonce un système de purge qui reste sous les 150 ms pour les tags, les hostnames et les préfixes, et autour de 250 ms en médiane pour la purge par URL unique. Une purge sans effet au bout d'une minute doit être considérée comme échouée.

Une exception légitime : avec le Tiered Cache activé, une purge par préfixe peut renvoyer EXPIRED plutôt que MISS à la requête suivante, car le niveau inférieur revalide auprès du niveau supérieur au lieu d'aller directement à votre origine. C'est le système qui fonctionne comme prévu, pas une purge ratée.

Si le contenu est encore périmé dix minutes plus tard, inutile d'attendre davantage ; réduisez le champ des causes : cache navigateur, mauvaise clé de cache, ou requête de purge qui n'a jamais été exécutée.

Quand une règle de cache semble ne rien faire

Les cache rules échouent en silence. Elles ne préviennent pas qu'elles n'ont jamais correspondu, et le dashboard n'affiche aucun compteur de déclenchement par règle. Quatre causes expliquent presque tout.

  • C'est la dernière règle correspondante qui gagne, pas la première. C'est le malentendu le plus coûteux de la liste, parce qu'il est l'inverse du comportement des anciennes Page Rules. Les cache rules se cumulent : plusieurs règles peuvent correspondre à la même requête et toutes s'appliquent, et lorsque deux règles fixent la même option, c'est la valeur de la dernière règle correspondante qui est retenue. Une règle de bypass permissive laissée en bas de liste annulera discrètement la règle soignée que vous venez d'écrire en haut.
  • L'expression ne correspond pas à ce que vous testez. Les règles s'évaluent sur la requête : une règle basée sur http.host, sur une extension de fichier ou sur un préfixe de chemin ignorera l'URL que vous interrogez si l'un de ces éléments diffère. Utilisez pour le test l'URL exacte visée par la règle, avec le même nom d'hôte et le même chemin.
  • Les en-têtes d'origine reprennent la main. L'Edge TTL propose trois modes, et deux d'entre eux rendent la décision à votre origine. « Use cache-control header if present, use default Cloudflare caching behavior if not » et « Use cache control-header if present, bypass cache if not » s'en remettent tous deux à l'en-tête de réponse. Seul « Ignore cache-control header and use this TTL » l'écrase. Si votre origine envoie no-store ou private et que votre règle respecte les en-têtes d'origine, la règle s'applique bel et bien et le contenu n'est toujours pas mis en cache. À noter aussi : Cloudflare lit d'abord Cloudflare-CDN-Cache-Control, puis CDN-Cache-Control, puis Cache-Control. Un CDN-Cache-Control: no-store l'emporte donc sur un Cache-Control: public, max-age=3600 pourtant irréprochable.
  • Edge TTL et Browser TTL ne sont pas le même réglage. L'Edge TTL fixe la durée pendant laquelle Cloudflare conserve l'objet ; le Browser TTL fixe la valeur de Cache-Control envoyée au visiteur. Modifier l'un laisse l'autre intact. Attention également au minimum d'Edge TTL, qui dépend du plan : deux heures sur Free, une heure sur Pro, une seconde sur Business et Enterprise. Sur un plan Free, vous ne pouvez pas régler un cache edge de cinq minutes, ce qui surprend quand on teste des TTL courts.

Un dernier point facile à mal interpréter : une cache rule réglée sur Bypass cache produit en général DYNAMIC dans l'en-tête de réponse plutôt que BYPASS, parce que la règle rend le contenu inéligible au cache avant même que la réponse de l'origine ne soit examinée. Dans ce cas, la valeur DYNAMIC est normale : la règle a bien exclu la ressource du cache.

Lire cf-cache-status sans deviner

Tout ce qui précède se confirme ou s'écarte avec un seul en-tête de réponse. Voici ce que signifie réellement chaque valeur, d'après les définitions de Cloudflare.

  • HIT : l'objet a été trouvé dans le cache edge et servi depuis là. Votre origine n'a pas été contactée.
  • MISS : l'objet était éligible au cache mais ne s'y trouvait pas, il vient donc de votre origine. Un MISS unique juste après une purge est le résultat attendu et correct.
  • EXPIRED : l'objet était dans le cache mais au-delà de son TTL, il a donc été récupéré à l'origine. Des EXPIRED fréquents signifient que votre TTL est plus court que ce que votre trafic demande.
  • REVALIDATED : l'objet était dans le cache, Cloudflare a demandé à votre origine s'il avait changé, et l'origine a répondu que non. C'est la valeur la plus souvent prise à tort pour un cache en bonne santé. Le corps de la réponse vient de l'edge, donc la bande passante est économisée, mais une requête part quand même vers votre origine et en revient à chaque appel : la latence et le volume de requêtes reçues par le serveur ne bougent presque pas. Elle apparaît quand stale-while-revalidate est absent, ou quand must-revalidate ou no-cache interdisent de servir du contenu périmé.
  • UPDATING : l'objet était expiré mais servi depuis le cache pendant que l'origine le rafraîchit en arrière-plan. C'est le statut attendu avec la revalidation asynchrone, et c'est bon signe.
  • STALE : servi depuis le cache au-delà de son expiration parce que Cloudflare n'a pas pu joindre votre origine. Un statut de cache qui est en réalité une alerte de disponibilité.
  • BYPASS : l'objet était éligible au cache au moment de la requête, mais la réponse de l'origine s'est révélée non cacheable. Un no-store, un private seul, un en-tête Set-Cookie, un Vary: * ou un corps plus volumineux que la limite de taille cacheable du plan aboutissent tous ici. La décision a été prise au moment de la réponse.
  • DYNAMIC : Cloudflare a décidé au moment de la requête que la ressource n'était pas éligible au cache, et est allé à l'origine sans même consulter le cache. La plupart du temps ce n'est pas une anomalie : le HTML et le JSON ne figurent pas dans la liste des extensions cacheables par défaut, donc une page HTML non mise en cache qui renvoie DYNAMIC est un comportement standard. Ce statut apparaît aussi quand une règle de bypass a correspondu, ou quand le mode développement est activé.
  • NONE/UNKNOWN : la réponse n'a jamais atteint la couche de cache. Un Worker a répondu sans sous-requête, une règle de sécurité a bloqué la requête, ou une règle de redirection a répondu la première.

L'en-tête Age constitue un bon second avis. Cloudflare le renseigne sur les réponses HIT, STALE et UPDATING, et pas sur MISS, DYNAMIC, BYPASS, ni sur les réponses EXPIRED et REVALIDATED qui ont revalidé auprès de l'origine. Une valeur Age qui grimpe de requête en requête confirme un objet réellement mis en cache ; l'absence totale de Age sur une ressource censée être cachée confirme l'inverse.

Le mode développement, souvent confondu avec une purge

Le mode développement est une source fréquente de faux diagnostics, dans les deux sens. Il suspend le cache edge et Polish pendant trois heures, sauf si vous le désactivez avant, et il ne purge rien du tout : les objets déjà en cache restent exactement où ils sont, ils ne sont simplement pas consultés tant que le mode est actif.

Le scénario type est celui-ci. Vous activez le mode développement, vous voyez vos modifications immédiatement, vous en concluez que le problème est réglé, et vous l'oubliez. Trois heures plus tard le mode expire tout seul, l'edge recommence à servir ses objets stockés, et l'ancien contenu revient sans que personne n'ait touché à un réglage. Ce que l'on observe alors n'est pas une purge défaillante, mais la fin du contournement. Tant que le mode est actif, attendez-vous à cf-cache-status: DYNAMIC sur tout, ce qui explique aussi qu'une zone en mode développement ressemble à un cache qui aurait cessé de fonctionner.

Si vous avez besoin d'un contournement de plus de trois heures, la recommandation de Cloudflare est une cache rule réglée sur Bypass cache, pas un mode développement réactivé en boucle.

Un exemple concret : ce site lui-même

cfgarage.com est hébergé sur Cloudflare Pages, et illustre bien le piège REVALIDATED. Demander deux fois de suite la feuille de style du site renvoie MISS puis REVALIDATED, jamais HIT, parce que la réponse porte cache-control: public, max-age=14400, must-revalidate. La directive must-revalidate fait exactement ce qu'elle annonce : dès que l'objet est considéré comme périmé, il ne peut plus être servi sans vérification auprès de l'origine, ce qui exclut le chemin stale-while-revalidate qui aurait produit HIT ou UPDATING.

Les pages HTML se comportent encore différemment : elles sont servies avec cache-control: public, max-age=0, must-revalidate et renvoient DYNAMIC, puisque le HTML ne fait pas partie des extensions cacheables par défaut et qu'aucune cache rule ne le déclare éligible.

Vue rapidement, cette zone donne l'impression d'un cache inutile. Interprétée correctement, chaque statut découle d'un en-tête choisi délibérément. Ce raisonnement vaut au-delà de ce site : avant de conclure que le cache est cassé, regardez ce que votre propre plateforme demande au cache de faire. Votre hébergeur, Cloudflare Pages ou le framework de votre site peut définir automatiquement ces en-têtes. Vérifiez les valeurs réellement envoyées, même si vous n'avez configuré aucun réglage de cache vous-même. Notre guide complémentaire sur un taux de cache hit trop bas sur Cloudflare traite l'autre moitié du problème, celle où le contenu devrait être mis en cache et ne l'est pas.

Le diagnostic pas à pas

Suivez ces étapes dans l'ordre. Chacune élimine un suspect, ce qui vous permet de toujours savoir ce que signifie le résultat suivant. D'autres checklists testées sur le terrain sont réunies dans notre hub de guides Cloudflare.

  1. Sortez le navigateur de l'équation. Demandez deux fois l'URL exacte et comparez :
    curl -sI https://www.exemple.com/style.css | grep -iE "cf-cache-status|cache-control|age|cf-ray"
    curl -sI https://www.exemple.com/style.css | grep -i "cf-cache-status"
    Si curl affiche le nouveau contenu, ou un MISS suivi d'un HIT, alors que votre navigateur montre encore l'ancienne page, l'edge va bien et il ne vous reste que le cache navigateur à traiter.
  2. Vérifiez que l'URL purgée est bien celle que vous testez. Incluez la query string, le protocole et le nom d'hôte exact :
    curl -sI "https://www.exemple.com/style.css?v=3" | grep -i "cf-cache-status"
    Si l'URL nue renvoie MISS et la version paramétrée HIT, vous tenez une clé de cache qui ne correspond pas, et la purge par préfixe est la réponse.
  3. Confirmez que la purge a été acceptée. Purgez une URL depuis Caching > Configuration > Custom Purge, puis redemandez-la immédiatement. La séquence attendue est MISS sur la première requête et HIT sur la seconde. Tout autre résultat signifie que la purge n'a pas atteint l'objet que vous croyez.
  4. Lisez ce que votre origine envoie réellement. Contournez le proxy et comparez :
    curl -sI --resolve www.exemple.com:443:203.0.113.10 https://www.exemple.com/style.css | grep -iE "cache-control|cdn-cache-control|set-cookie|vary"
    Remplacez l'adresse par celle de votre origine. Un no-store, un private seul, un Set-Cookie sur une ressource publique ou un Vary: * expliquent immédiatement un BYPASS, et un en-tête CDN-Cache-Control prendra discrètement le pas sur ce que dit Cache-Control.
  5. Vérifiez le mode développement. Ouvrez Caching > Configuration. Si l'interrupteur est actif, tout ce que vous observez est un contournement, pas un cache. Désactivez-le et retestez avant de conclure quoi que ce soit.
  6. Auditez les cache rules, de bas en haut. Ouvrez Caching > Cache Rules et lisez la liste en partant du bas, puisque c'est la dernière règle correspondante qui l'emporte en cas de conflit. Vérifiez ensuite Rules > Page Rules pour d'anciennes entrées, en gardant à l'esprit que les cache rules ont priorité sur les Page Rules par conception.
  7. Examinez la règle censée se déclencher. Assurez-vous que son expression correspond à l'URL testée, que l'Edge TTL ne s'en remet pas silencieusement aux en-têtes d'origine, et que l'expression n'est pas limitée au seul GET, ce qui empêcherait aussi les purges par URL de correspondre.
  8. Et seulement ensuite, envisagez Purge Everything. Utilisez-la comme étape de confirmation, pas comme habitude, et attendez-vous à une rafale de trafic vers l'origine juste après. Si le contenu est correct après une purge totale puis redevient faux plus tard, le problème est une règle ou un en-tête, pas le cache.

Les erreurs qui maintiennent l'ancienne version en vie

  • Tester dans le navigateur qui a causé la confusion. Un rechargement forcé ne vide pas tout, et les service workers ajoutent un troisième cache que le dashboard ne voit pas. Prenez curl ou une fenêtre privée comme référence.
  • Purger en boucle au lieu de diagnostiquer une fois. Une purge sans effet la première fois n'en aura pas davantage la cinquième, et sur un plan Free le plafond est de toute façon de cinq requêtes par minute.
  • Fixer un Browser TTL long sur des fichiers modifiés en place. Un cache navigateur d'un an n'est sûr que sur des noms de fichiers versionnés. Sur un fichier dont le nom ne change jamais, c'est une décision irréversible pendant un an.
  • Laisser le mode développement actif comme contournement. Il expire seul au bout de trois heures, et le problème initial réapparaît sans qu'aucun changement visible ne puisse être mis en cause.
  • Supposer que l'ordre des règles se comporte comme celui des Page Rules. Plusieurs Cache Rules peuvent s'appliquer à une même requête. Si elles définissent des valeurs différentes pour un même réglage, la dernière règle correspondante l'emporte. Vérifiez donc aussi les règles situées plus bas dans la liste.

Questions fréquentes

J'ai lancé Purge Everything et le cache Cloudflare ne se vide toujours pas. Pourquoi ?

Dans la majorité des cas, le cache edge s'est bien vidé et c'est votre navigateur qui sert sa propre copie. Une purge retire les objets des datacenters Cloudflare uniquement ; elle n'atteint jamais les caches stockés sur les machines de vos visiteurs. La documentation Cloudflare le dit sans ambiguïté : purger le cache Cloudflare n'affecte pas les ressources stockées par le navigateur d'un visiteur. Retestez avec curl ou en navigation privée avant de toucher au moindre réglage : si curl renvoie la nouvelle version et pas votre navigateur, la purge a fonctionné et il ne reste que le cache navigateur à traiter.

Comment vider le cache Cloudflare ?

Depuis le dashboard, ouvrez Caching > Configuration. Purge Everything vide toute la zone, et Custom Purge permet de purger par URL, par hostname, par tag ou par préfixe. Ces cinq méthodes sont disponibles sur tous les plans, Free compris, depuis avril 2025. La purge par URL unique est la méthode que Cloudflare recommande, parce que Purge Everything renvoie d'un coup toutes les requêtes suivantes vers votre origine et peut faire grimper sa charge.

Pourquoi ma cache rule Cloudflare ne fonctionne pas ?

Trois causes couvrent presque tous les cas. L'expression ne correspond pas à la requête que vous testez, donc la règle ne se déclenche jamais. Une autre cache rule située plus bas dans la liste correspond à la même requête et écrase votre réglage, car les cache rules se cumulent et, en cas de conflit, c'est la dernière règle correspondante qui l'emporte. Ou la règle se déclenche correctement mais l'Edge TTL est resté sur une option qui respecte les en-têtes d'origine, et un no-store ou un private envoyé par votre serveur décide alors du résultat.

J'ai purgé l'URL et le fichier n'est toujours pas purgé. Qu'est-ce qui m'échappe ?

La query string fait partie de la clé de cache par défaut : purger /style.css ne purge pas /style.css?v=3. Le protocole et le nom d'hôte doivent aussi correspondre exactement, et le chemin est sensible à la casse même si le nom d'hôte ne l'est pas. Une purge par URL lancée depuis le dashboard échoue également quand une cache rule définit une clé de cache personnalisée à partir d'en-têtes ou de cookies, ou quand l'expression de la règle ne correspond qu'aux requêtes GET. La purge par préfixe ou par tag est le repli fiable.

Combien de temps met une purge Cloudflare à se propager ?

Quelques secondes, pas quelques minutes. Cloudflare annonce une latence de purge inférieure à 150 ms pour les tags, hostnames et préfixes, et environ 250 ms en médiane pour la purge par URL unique. Si le contenu est encore périmé une minute plus tard, ce n'est pas la purge qui est lente : vous avez affaire à un cache navigateur, à une clé de cache qui ne correspond pas, ou à une requête de purge bloquée par les quotas. Sur un plan Free, la limite est de cinq requêtes de purge par minute et par compte pour hostname, tag, préfixe et Purge Everything.

cf-cache-status REVALIDATED signifie-t-il que mon cache fonctionne ?

En partie seulement. REVALIDATED signifie que l'objet était bien dans le cache edge, mais que Cloudflare a demandé à votre origine s'il avait changé et que l'origine a répondu que non. La bande passante est économisée puisque le corps de la réponse vient du cache, mais l'aller-retour vers votre origine a lieu à chaque requête : la latence et le nombre de requêtes reçues par le serveur ne baissent quasiment pas. Cette valeur vient typiquement d'un must-revalidate ou d'un no-cache dans votre en-tête Cache-Control. Voir REVALIDATED au lieu de HIT est le signe habituel d'un cache techniquement actif mais qui ne fait pas le travail attendu.

Des purges qui ne changent rien, des règles qui ne se déclenchent jamais ?

CF Garage lit vos en-têtes, reconstitue vos clés de cache et remet vos règles de cache dans un ordre lisible. Tarif fixe, comptes rendus écrits, garantie de satisfaction.

Voir nos offres

Ressources et guides complémentaires