---
title: "Cloudflare veut compresser le cache une fois, pas Internet à chaque requête"
locale: "fr"
url: "https://irz.fr/fr/articles/cloudflare-cache-zstd-stockage-fr"
markdown_url: "https://irz.fr/fr/articles/cloudflare-cache-zstd-stockage-fr.md"
category: "tech"
tags: ["Cloudflare", "cache", "Zstandard", "Pingora", "CDN"]
published_at: "2026-09-23T09:02:00.000Z"
author: "Hugo Marchal"
translation: "https://irz.fr/en/articles/cloudflare-cache-zstd-storage-en.md"
---

# Cloudflare veut compresser le cache une fois, pas Internet à chaque requête

Cache Transcoding stocke certains textes en zstd, les garde compressés entre data centers puis les décode au bord. Cloudflare échange ainsi un peu de CPU contre davantage de cache utile.

Le prototype présenté par Cloudflare le 1er septembre 2026 part d'une idée qui paraît presque trop simple pour mériter un nom : lorsqu'un fichier texte arrive **non compressé** dans le cache, pourquoi continuer à le stocker et à le transporter ainsi entre data centers ?[1](https://blog.cloudflare.com/cache-transcoding/)

Cloudflare appelle cette expérience **Cache Transcoding**. Sur un cache miss éligible, le proxy Pingora compresse le corps en **Zstandard niveau 3** avant de l'écrire sur disque. La représentation zstd reste ensuite compressée lorsqu'elle traverse les niveaux du Tiered Cache. Au dernier saut, celui qui fait face au client, Cloudflare la décompresse et renvoie les octets d'origine.[1](https://blog.cloudflare.com/cache-transcoding/)

Le navigateur n'a donc pas besoin de recevoir du zstd ni même de savoir que le cache l'a utilisé.

C'est précisément ce qui rend l'expérience intéressante : Cloudflare traite la compression comme une **propriété interne du stockage**, séparée du format HTTP vu à l'extérieur.

## Une seule compression

Le coût se répartit de manière asymétrique : encoder demande du CPU au moment où l'objet entre dans le cache, tandis que décoder en demande **chaque fois qu'il est servi**.[1](https://blog.cloudflare.com/cache-transcoding/)

Cloudflare mesure sur son corpus contrôlé :

- **2,834×** de ratio de compression ;
- **4,31 ns par octet** pour l'encodage, environ 232 MB/s ;
- **1,56 ns par octet** pour le décodage, environ 641 MB/s.[1](https://blog.cloudflare.com/cache-transcoding/)

L'encodage est donc la partie la plus chère par octet, mais il n'arrive qu'au remplissage du cache. Si le même objet sert dix, cent ou mille requêtes, on ne le recompresse pas mille fois.

> **Un fill, beaucoup de hits**
> Schéma IRZ du coût CPU de Cache Transcoding : une compression lors du remplissage, une décompression à chaque hit
> - LE CPU N’EST PAS PAYÉ AU MÊME MOMENT
> - CACHE FILL
encode zstd
4,31 ns/octet
> - DISQUE
objet zstd
≈ 1/2,834
> - HIT
decode
1,56 ns/octet
> - L’encodage est payé une fois par remplissage. Le décodage revient sur chaque service, donc le vrai compromis dépend de la réutilisation.
> Mesures du corpus contrôlé Cloudflare. Elles décrivent le prototype, pas un coefficient universel applicable à tout le Web.

C'est une différence fondamentale avec la compression à la volée d'une réponse HTTP.

Ici, Cloudflare ne prend pas l'objet brut à chaque hit pour fabriquer encore une nouvelle archive. Le cache possède déjà sa représentation compacte. Le travail répété est la **décompression**, opération précisément choisie parce que zstd sait la faire vite.[1](https://blog.cloudflare.com/cache-transcoding/)[3](https://github.com/facebook/zstd)

## Le cache comme codec

Historiquement, explique Cloudflare, son cache conserve l'encodage fourni par l'origine. Si le serveur d'origine envoie une réponse sans Content-Encoding, ces octets non compressés peuvent finir stockés tels quels et transférés sous cette forme entre data centers.[1](https://blog.cloudflare.com/cache-transcoding/)

Cache Transcoding ajoute une autre couche : le proxy conserve dans les métadonnées le fait que l'objet sur disque est encodé en zstd, ainsi que sa longueur originale. Un marqueur empêche une autre couche de cache de recompresser un objet déjà transformé.[1](https://blog.cloudflare.com/cache-transcoding/)

Cette information devient particulièrement utile avec Tiered Cache.

Si un cache inférieur rate mais qu'un cache supérieur possède déjà l'objet, la représentation zstd circule **directement entre les deux caches**. Elle reste compacte sur le réseau interne et sur le disque du cache inférieur ; la décompression attend le dernier saut vers le client.[1](https://blog.cloudflare.com/cache-transcoding/)

Le cache devient ainsi autre chose qu'un entrepôt de réponses reçues : il choisit sa propre représentation physique.

Pingora est un bon endroit pour placer cette décision parce que ce framework proxy de Cloudflare, écrit en Rust et publié en open source, est précisément conçu pour les chemins réseau à grande échelle.[2](https://github.com/cloudflare/pingora)

## Refuser la majorité des octets

Une compression rentable commence par savoir quoi **ne pas** compresser.

Dans l'échantillon de trafic décrit par Cloudflare, images, vidéos et polices ne représentent que **21,4 % des requêtes**, mais **63,3 % des octets**.[1](https://blog.cloudflare.com/cache-transcoding/)

Ces formats étant souvent déjà fortement compressés, les repasser dans zstd brûlerait du CPU pour presque aucun gain.

Le texte a un profil différent : HTML, JSON, CSS et JavaScript représentent **67,3 % des requêtes** et **22,3 % des octets**. Dans cette tranche texte, environ **71 %** arrive sans Content-Encoding.[1](https://blog.cloudflare.com/cache-transcoding/)

Le prototype exige donc simultanément un statut **200 OK**, aucun Content-Encoding, un Content-Type textuel compressible, un Content-Length connu et au moins **4 KiB** de contenu.[1](https://blog.cloudflare.com/cache-transcoding/)

Les requêtes range, les sous-requêtes de slices, les contenus binaires, les réponses déjà compressées, les tailles inconnues et certains chemins de compression upstream sont laissés tranquilles.[1](https://blog.cloudflare.com/cache-transcoding/)

La meilleure optimisation reste celle qui ne tourne pas.

## Quatre kibioctets

Le seuil de 4 KiB n'est pas une vérité de la compression.

Cloudflare l'a choisi parce qu'il retire beaucoup de minuscules objets de la file de travail tout en abandonnant seulement **environ 1 % des octets** qui auraient autrement été éligibles dans son échantillon.[1](https://blog.cloudflare.com/cache-transcoding/)

En dessous, le coût fixe par objet commence à manger le bénéfice ; au-dessus, le système récupère presque tout le gain de stockage mesuré.

Même chose pour le niveau zstd : le prototype commence au **niveau 3**, un compromis volontairement prudent. Cloudflare prévoit d'essayer des niveaux plus élevés si le gain de ratio justifie leur coût CPU supplémentaire.[1](https://blog.cloudflare.com/cache-transcoding/)

Cette approche correspond à la philosophie de Zstandard lui-même.

L'implémentation de référence expose une large plage de niveaux afin de déplacer progressivement le curseur entre vitesse et ratio, tout en conservant une décompression rapide.[3](https://github.com/facebook/zstd) Meta décrivait déjà en 2018 des gains différents selon que zstd remplaçait zlib, LZ4 ou XZ dans des systèmes dont les priorités n'étaient pas les mêmes.[4](https://engineering.fb.com/2018/12/19/core-infra/zstandard/)

Il n'existe pas un « meilleur réglage zstd ». Il existe un endroit où le CPU coûte moins cher que les octets.

## Un million de requêtes

Le chiffre **2,834×** mérite une grosse étiquette « test contrôlé » : Cloudflare a fait passer **plus d'un million de requêtes** à travers dix serveurs de cache. La moitié de la campagne utilisait Tiered Cache, l'autre moitié non.[1](https://blog.cloudflare.com/cache-transcoding/)

Les deux objets de test faisaient environ **195 KiB** et **272 KiB** et avaient été choisis parce qu'ils étaient compressibles. Tous deux se sont réduits d'environ 2,8 fois.[1](https://blog.cloudflare.com/cache-transcoding/)

Cloudflare le précise noir sur blanc : ce corpus donne un signal propre pour valider l'architecture, **mais il ne représente pas tous les objets texte d'Internet**. Il faudrait un corpus plus large avant de traiter ce ratio comme une constante de flotte.[1](https://blog.cloudflare.com/cache-transcoding/)

Cette réserve change complètement la lecture du titre « save petabytes » : le prototype ne démontre évidemment pas que chaque pétaoctet actuel deviendra automatiquement 353 téraoctets.

Il montre qu'une catégorie non négligeable d'objets actuellement stockés sans compression pourrait acheter beaucoup plus de densité si le ratio observé se maintient suffisamment bien sur du trafic réel.

> **Mesuré, modélisé, encore inconnu**
> - 2,834× sur deux objets contrôlés, plus d’un million de requêtes et 10 serveurs: Mesuré
> - quelques pourcents de CPU supplémentaire avec les hypothèses de trafic et de réutilisation testées: Modélisé
> - 67,3 % des requêtes sont du texte ; environ 71 % de cette tranche arrive non compressée: Échantillon trafic
> - le ratio moyen et le budget CPU sur un corpus représentatif de toute la flotte: Encore inconnu
> Le blog Cloudflare parle explicitement d’un prototype et demande un corpus plus large avant généralisation.

## Quelques pourcents

Le modèle de Cloudflare place le surcoût CPU à **quelques pourcents** dans les hypothèses de trafic et de réutilisation évaluées avec zstd niveau 3.[1](https://blog.cloudflare.com/cache-transcoding/)

À l'échelle d'un CDN, ce pourcentage de CPU peut représenter beaucoup de machines et beaucoup d'électricité. Mais l'autre côté de l'équation est lui aussi mondial : plus de contenu tenu dans la même capacité disque, moins d'évictions dues à la taille d'objets non compressés et moins d'octets échangés entre niveaux de cache.[1](https://blog.cloudflare.com/cache-transcoding/)

Le calcul économique devient presque contre-intuitif : on dépense du calcul pour économiser du stockage et du réseau.

Ce type d'échange est courant dans les systèmes distribués, mais Cache Transcoding le rend particulièrement lisible parce que les trois unités sont mesurables : nanosecondes CPU par octet, octets occupés sur disque, octets envoyés sur le backbone.

Le résultat intéressant n'est pas que zstd compresse bien, propriété déjà connue, mais qu'une architecture qui permet de déplacer le curseur sans modifier l'origine ni le client.

## Pourquoi pas seulement les hits chauds ?

L'équipe a aussi testé une intuition très naturelle : ne compresser que les objets populaires, puisqu'un objet chaud sera servi plusieurs fois et devrait mieux amortir son coût d'encodage.

Le résultat ne suit pas complètement cette intuition.

Le décodage arrive sur **chaque service**, qu'un objet soit vaguement populaire ou extrêmement chaud. Limiter le transcodage aux objets les plus demandés réduit donc les économies de stockage sans faire disparaître une part équivalente du coût CPU.[1](https://blog.cloudflare.com/cache-transcoding/)

La politique plus simple a mieux fonctionné dans le modèle : compresser tous les textes éligibles de 4 KiB ou plus.[1](https://blog.cloudflare.com/cache-transcoding/)

C'est un joli cas où une heuristique « intelligente » apporte moins qu'une frontière bête mais bien placée.

Le système ne cherche donc pas à deviner l'avenir de chaque objet ; il vérifie seulement si l'objet appartient à une classe où la compression a de bonnes chances d'être rentable.

## Pas encore Internet

Cloudflare emploie tout au long de son article le mot **prototype**,[1](https://blog.cloudflare.com/cache-transcoding/) précaution qu'il serait assez créatif de convertir ensuite en annonce de déploiement mondial.

La campagne valide des chemins de cache miss, cache hit, remplissage simple et Tiered Cache. Les traces Jaeger et les métriques Prometheus ont servi à vérifier où encodage et décodage se produisaient.[1](https://blog.cloudflare.com/cache-transcoding/)

Cette campagne constitue une validation d'architecture sérieuse sans encore prouver le comportement sur la distribution complète du trafic Cloudflare.

Le texte le dit lui-même : un corpus plus large est nécessaire avant de considérer le ratio mesuré comme représentatif de la flotte.[1](https://blog.cloudflare.com/cache-transcoding/)

Il reste aussi des paramètres ouverts : seuil de taille, niveau zstd, catégories éligibles, budget CPU acceptable et comportement sur des contenus texte beaucoup moins compressibles.

Un système à cette échelle n'est pas terminé quand l'algorithme marche.

Il est terminé quand l'algorithme marche **sans déplacer le problème vers une autre ressource plus chère**.

## Le format intérieur

La meilleure idée de Cache Transcoding est peut-être moins Zstandard que le droit donné au cache de ne pas conserver les octets exactement sous la forme où ils sont arrivés.

Une base de données transforme déjà les données qu'elle stocke et un système de fichiers compressé fait de même ; Cloudflare applique cette logique à un objet HTTP tout en gardant la transformation invisible aux extrémités.

L'origine peut continuer à produire une réponse identity, le client à recevoir une représentation qu'il comprend, tandis qu'entre les deux le cache choisit une forme plus économique pour lui-même.

Cette indépendance rend le système adaptable : aujourd'hui zstd niveau 3 et 4 KiB, demain peut-être un autre seuil, un autre niveau ou une politique différente si les mesures l'exigent.

La représentation interne devient un détail d'implémentation plutôt qu'un contrat externe.

## Acheter du cache avec du CPU

La formule « pétaoctets économisés » attire naturellement l'œil, alors que le prototype devient plus intéressant lorsqu'on le réduit à ses coûts concrets.

Une fois : **4,31 ns par octet** pour encoder.

À chaque service : **1,56 ns par octet** pour décoder.

Sur disque et entre caches : environ **un tiers de la taille** pour les deux objets du test.[1](https://blog.cloudflare.com/cache-transcoding/)

À l'échelle de Cloudflare, quelques pourcents de CPU supplémentaires peuvent être une dépense énorme. Mais ajouter des pétaoctets de capacité physique et transporter davantage de données entre data centers coûte également très cher.

Cache Transcoding cherche le point où le calcul disponible vaut moins cher que le stockage qu'il libère.

Le résultat 2026 n'est donc pas encore « Cloudflare a recompressé son CDN ». Il est plus utile à ce stade : **Cloudflare a construit un endroit précis dans Pingora où ce compromis peut enfin être mesuré sans le faire payer à chaque origine et à chaque client**.

Et dans un système distribué, rendre un compromis mesurable est souvent la première vraie optimisation.

## References

1. [Aashi Patel, How we could save petabytes of cache storage with Zstandard and Pingora, Cloudflare Blog, 1er septembre 2026](https://blog.cloudflare.com/cache-transcoding/)
2. [Cloudflare, Pingora, dépôt GitHub](https://github.com/cloudflare/pingora)
3. [facebook/zstd, implémentation de référence Zstandard](https://github.com/facebook/zstd)
4. [Meta Engineering, Zstandard: How Facebook increased compression speed, 19 décembre 2018](https://engineering.fb.com/2018/12/19/core-infra/zstandard/)
