ZSTD vs Brotli vs GZIP : choisir la compression pour les API
Comparez ZSTD, Brotli et GZIP pour les APIs : vitesse, ratio de compression, coût CPU et choix pratiques par défaut pour les payloads JSON et binaires en production.

Ce qu'est la compression d'API (et quand elle vaut le coup)
La compression des réponses d'API signifie que votre serveur encode le corps de la réponse (souvent du JSON) en un flux d'octets plus petit avant de l'envoyer sur le réseau. Le client (navigateur, application mobile, SDK ou un autre service) le décompresse ensuite. Sur HTTP, cela se négocie via des en-têtes comme Accept-Encoding (ce que le client accepte) et Content-Encoding (ce que le serveur a choisi).
Ce que ça apporte aux API
La compression vous apporte principalement trois choses :
- Moins de bande passante : des réponses plus petites consomment moins d'octets bout en bout.
- Latence plus faible sur les liens contraints : moins d'octets signifie souvent des téléchargements plus rapides sur mobile, Wi‑Fi congestionné et appels inter-régions.
- Coût d'egress réduit : si vous payez les données sortantes, réduire la taille de transfert peut réduire directement la facture.
Le compromis est simple : la compression économise de la bande passante mais coûte du CPU (compression/décompression) et parfois de la mémoire (buffers). La pertinence dépend de votre goulot d'étranglement.
Quand la compression est la plus utile
La compression brille généralement quand les réponses sont :
- Riche en texte et répétitives, comme le JSON, les réponses GraphQL, le HTML ou les logs.
- Moyennes à grandes, où gagner des dizaines ou centaines de kilo-octets compte.
- Servies sur des réseaux lents ou coûteux, comme mobile, clients internationaux ou trafic inter-régions.
Si vous renvoyez de grandes listes JSON (catalogues, résultats de recherche, analytics), la compression est souvent l'un des gains les plus faciles à obtenir.
Quand elle aide le moins
La compression est souvent une mauvaise utilisation du CPU quand les réponses sont :
- Très petites (par exemple, quelques centaines d'octets). Le coût des en-têtes + CPU peut dépasser l'économie.
- Déjà compressées (JPEG/PNG, MP4, ZIP, beaucoup de PDFs). Recompresser donne rarement un gain et peut même augmenter la taille.
- Services liés au CPU (endpoints très sollicités par le calcul). Ajouter la compression peut augmenter la latence tail.
Les axes de décision de ce guide
Quand vous choisissez entre ZSTD vs Brotli vs GZIP pour la compression d'API, la décision pratique se résume souvent à :
- Réduction de taille (ratio de compression)
- Latence (temps serveur jusqu'au premier octet + décodage client)
- Support client (ce que vos clients et intermédiaires gèrent de manière fiable)
Tout le reste dans cet article concerne l'équilibre de ces trois éléments selon votre API et vos patterns de trafic.
ZSTD vs Brotli vs GZIP : comparaison rapide
Les trois réduisent la taille du payload, mais optimisent pour des contraintes différentes — vitesse, ratio ou compatibilité.
Résumé en un coup d'œil
- ZSTD (Zstandard) : souvent le meilleur compromis pour les APIs quand vous tenez à une basse latence et un CPU prévisible. Bon ratio sans être lent.
- Brotli : souvent gagnant pour le plus petit nombre d'octets sur le fil, surtout pour les réponses riches en texte. Les niveaux élevés peuvent coûter plus de CPU.
- GZIP : l'option « qui marche partout ». Très répandu et simple à opérationnaliser, mais typiquement plus lent et/ou plus volumineux que les alternatives modernes pour un budget CPU comparable.
Forces typiques (et ce que ça signifie pour les API)
Vitesse ZSTD : excellent quand votre API est sensible à la latence tail ou que vos serveurs sont liés au CPU. Il peut compresser assez vite pour que le surcoût soit négligeable face au temps réseau — surtout pour les réponses JSON moyennes à grandes.
Ratio Brotli : meilleur quand la bande passante est la contrainte principale (clients mobiles, egress coûteux, livraison via CDN) et que les réponses sont majoritairement textuelles. Les petits payloads peuvent en valoir la peine même si la compression prend plus de temps.
Compatibilité GZIP : meilleur quand vous avez besoin du support client maximal sans risque de négociation (SDK anciens, clients embarqués, proxies legacy). C'est un baseline sûr même s'il n'est pas le plus performant.
Ce que change le “niveau de compression”
Les « niveaux » de compression sont des presets qui font échanger temps CPU contre taille de sortie :
- Niveaux bas : compression rapide, payloads plus grands. Bon pour les APIs temps réel.
- Niveaux élevés : payloads plus petits, compression plus lente (et parfois plus de mémoire). Mieux pour les grandes réponses cacheables.
La décompression est généralement beaucoup moins coûteuse que la compression pour les trois formats, mais des niveaux très élevés peuvent encore augmenter la consommation CPU/batterie côté client — important pour le mobile.
Règle simple
- Choix par défaut : utilisez ZSTD pour la plupart des APIs JSON/REST/GraphQL où la latence compte.
- Passez à Brotli : quand vous optimisez pour le minimum d'octets (réponses textuelles, distribution via CDN, réseaux lents) et que vous pouvez tolérer plus de CPU.
- Restez sur GZIP : quand vous avez besoin d'une compatibilité large ou si votre infra/outillage ne supporte pas les encodages plus récents.
Ratio de compression vs latence : le compromis central
La compression est souvent vendue comme « réponses plus petites = APIs plus rapides ». C'est souvent vrai sur des réseaux lents ou coûteux — mais ce n'est pas automatique. Si la compression ajoute suffisamment de temps CPU côté serveur, vous pouvez obtenir des requêtes plus lentes malgré moins d'octets envoyés.
Où va le temps
Il est utile de séparer deux coûts :
- Temps de compression (côté serveur) : travail fait avant que le serveur puisse commencer à envoyer des octets. Cela peut s'ajouter directement au temps de réponse (TTFB).
- Temps de décompression (côté client) : travail fait après réception des octets. Généralement moins coûteux que la compression, mais pertinent sur des appareils peu puissants.
Un fort ratio de compression peut réduire le temps de transfert, mais si la compression ajoute (par exemple) 15–30 ms de CPU par réponse, vous pouvez perdre plus de temps que vous n'en gagnez — surtout sur les connexions rapides.
Le piège de la latence tail sous charge
Sous charge, la compression peut nuire davantage à la latence p95/p99 que p50. Quand l'utilisation CPU monte, les requêtes font la queue. La mise en file amplifie de petits coûts par requête en gros délais — la latence moyenne peut rester correcte, mais les utilisateurs les plus lents en pâtissent.
Mesurez comme une fonctionnalité de performance
Ne devinez pas. Faites un test A/B ou un déploiement progressif et comparez :
- Latence p50 et p95 (et idéalement p99)
- Utilisation CPU et saturation des instances API
- Tailles de réponse et TTFB
Testez avec des patterns de trafic et des payloads réalistes. Le « meilleur » niveau de compression est celui qui réduit le temps total, pas seulement les octets.
Coûts CPU et mémoire côté serveur et client
La compression n'est pas “gratuite” — elle transfère du travail du réseau vers le CPU et la mémoire des deux côtés. Dans les APIs, cela se traduit par un temps de traitement par requête plus élevé, une empreinte mémoire plus grande et parfois des ralentissements côté client.
Où le CPU est consommé
La plupart du CPU est consommée en compressant les réponses. La compression cherche des motifs, construit des états/dictionnaires et écrit la sortie encodée.
La décompression est typiquement moins coûteuse, mais reste pertinente :
- Les serveurs peuvent décompresser des requêtes (rare pour les APIs JSON, plus fréquent pour des uploads ou événements en batch).
- Les clients décompressent les réponses sur le chemin critique avant de parser le JSON.
Si votre API est déjà liée au CPU (serveurs d'apps très sollicités, authentifications lourdes, requêtes coûteuses), activer un niveau élevé de compression peut augmenter la latence tail même si les payloads rétrécissent.
Considérations mémoire
La compression peut augmenter l'utilisation mémoire :
- Buffers : les implémentations peuvent nécessiter des buffers d'entrée/sortie ; les gros payloads impliquent des buffers plus grands.
- Buffering complet vs streaming : la compression en streaming peut commencer à envoyer plus tôt et garder la mémoire plus stable, alors que le buffering complet peut gonfler le pic mémoire par requête.
Dans des environnements conteneurisés, des pics mémoire plus élevés peuvent se traduire par des OOM kills ou des limites plus strictes réduisant la densité.
Impact sur l'autoscaling et les limites de conteneur
La compression ajoute des cycles CPU par réponse, réduisant le débit par instance. Cela peut déclencher l'autoscaling plus tôt, augmentant les coûts. Un schéma courant : bande passante en baisse, mais dépense CPU en hausse — le bon choix dépend de la ressource qui vous manque.
Pourquoi la vitesse de décompression importe côté client
Sur mobile ou appareils peu puissants, la décompression rivalise avec le rendu, l'exécution JS et la batterie. Un format qui sauve quelques Ko mais prend plus de temps à décompresser peut sembler plus lent, surtout quand le “temps jusqu'aux données utilisables” compte.
ZSTD pour les APIs : points forts, limites et valeurs par défaut
Zstandard (ZSTD) est un format moderne conçu pour offrir un bon ratio de compression sans ralentir votre API. Pour de nombreuses APIs riches en JSON, c'est un excellent « par défaut » : réponses nettement plus petites que GZIP pour une latence comparable ou inférieure, et une décompression très rapide côté client.
À quoi ZSTD est le mieux adapté
ZSTD est précieux quand vous vous souciez du temps de bout en bout, pas seulement des octets. Il compresse rapidement et décompresse extrêmement vite — utile pour des APIs où chaque milliseconde CPU concurrence le traitement de la requête.
Il fonctionne bien sur un large éventail de tailles de payload : JSON petit à moyen voit souvent des gains, et les grandes réponses profitent encore plus.
Niveaux de compression sensés pour les APIs
Pour la plupart des APIs, commencez par des niveaux bas (généralement 1–3). Ils offrent souvent le meilleur compromis latence/taille.
Augmentez les niveaux seulement quand :
- Les payloads sont grands (centaines de Ko à Mo)
- La bande passante est chère ou contrainte
- Vous avez mesuré que le CPU n'est pas le goulot
Approche pragmatique : un défaut global bas, puis augmenter sélectivement le niveau pour quelques endpoints qui renvoient de grosses réponses.
Streaming et mode dictionnaire
ZSTD supporte le streaming, ce qui peut réduire la mémoire maximale et commencer l'envoi plus tôt pour les grandes réponses.
Le mode dictionnaire peut être un grand gain pour des APIs qui retournent beaucoup d'objets similaires (clés répétées, schémas stables). C'est efficace quand :
- Les payloads sont petits mais fréquents
- Vous pouvez gérer des dictionnaires versionnés en toute sécurité
Limites de compatibilité à surveiller
Le support côté serveur est simple dans de nombreux écosystèmes, mais la compatibilité client peut décider du choix. Certains clients HTTP, proxies et gateways n'annoncent ou n'acceptent pas Content-Encoding: zstd par défaut.
Si vous servez des consommateurs tiers, gardez un fallback (généralement GZIP) et n'activez ZSTD que lorsque Accept-Encoding l'inclut clairement.
Brotli pour les APIs : quand il gagne et quand il ne vaut pas le coup
Brotli est conçu pour compresser très efficacement le texte. Sur JSON, HTML et autres payloads « verbeux », il bat souvent GZIP sur le ratio — surtout à des niveaux élevés.
Où Brotli gagne
Les réponses textuelles sont le terrain de prédilection de Brotli. Si votre API envoie de gros documents JSON (catalogues, résultats de recherche, blobs de configuration), Brotli peut réduire sensiblement les octets, ce qui aide sur réseaux lents et réduit le coût d'egress.
Brotli est aussi fort quand vous pouvez compresser une fois et servir beaucoup (réponses cacheables, ressources versionnées). Dans ce cas, Brotli en haut niveau peut valoir le coût CPU car il est amorti.
Où Brotli déçoit
Pour les réponses dynamiques générées à chaque requête, les meilleurs ratios de Brotli demandent souvent des niveaux élevés coûteux en CPU et qui augmentent la latence. Une fois le temps de compression pris en compte, le gain réel sur ZSTD (ou même un GZIP bien réglé) peut être plus petit que prévu.
Il est aussi moins pertinent pour les payloads qui ne se compressent pas bien (données déjà compressées, formats binaires), où vous brûlez du CPU pour peu de résultat.
Guide pratique par niveaux
- Compression à l'exécution : utilisez des niveaux bas (souvent 1–4) pour éviter des pointes CPU.
- Précompressé/statique : les niveaux plus élevés (souvent 8–11) peuvent valoir le coup quand ils sont amortis sur de nombreuses requêtes.
Support client
Les navigateurs supportent généralement bien Brotli en HTTPS, ce qui explique sa popularité sur le trafic web. Pour des clients API non-navigateur (SDK mobiles, IoT, piles HTTP anciennes), le support peut être inégal — négociez avec Accept-Encoding et gardez un fallback (typiquement GZIP).
GZIP pour les APIs : compatibilité et performance pratique
GZIP reste la réponse par défaut pour la compression d'API car c'est l'option la plus universellement supportée. Presque tous les clients HTTP, navigateurs, proxies et gateways comprennent Content-Encoding: gzip, et cette prévisibilité compte quand vous ne contrôlez pas entièrement les intermédiaires.
Pourquoi il reste courant
L'avantage n'est pas que GZIP soit le « meilleur » — c'est qu'il est rarement le mauvais choix. Beaucoup d'organisations ont des années d'expérience opérationnelle avec, des defaults sensés dans leurs serveurs web, et moins de surprises avec des intermédiaires qui pourraient mal gérer les encodages plus récents.
Niveaux pratiques pour les APIs
Pour les payloads API (souvent du JSON), les niveaux moyens à bas sont le meilleur compromis. Des niveaux comme 1–6 offrent la majeure partie de la réduction de taille tout en gardant le CPU raisonnable.
Les niveaux très élevés (8–9) peuvent gagner un peu plus, mais le CPU additionnel vaut rarement le coût pour un trafic dynamique où la latence compte.
Comparaison sur CPUs modernes
Sur du matériel moderne, GZIP est généralement plus lent que ZSTD pour un ratio comparable, et il ne peut souvent pas égaler les meilleurs ratios de Brotli sur du texte. Dans des charges API réelles :
- ZSTD gagne souvent en vitesse par octet économisé.
- Brotli peut gagner sur la taille pour le texte hautement compressible, mais à coût CPU variable selon les réglages.
- GZIP reste compétitif parce que c'est « suffisamment rapide » et très optimisé partout.
Cas limites de compatibilité
Si vous devez supporter des clients anciens, des dispositifs embarqués, des proxies d'entreprise stricts ou des gateways legacy, GZIP est le pari le plus sûr. Certains intermédiaires suppriment les encodages inconnus, ne les transmettent pas ou cassent la négociation — des problèmes beaucoup moins fréquents avec GZIP.
Si votre environnement est mixte ou incertain, commencer par GZIP (et ajouter ZSTD/Brotli pour les chemins que vous contrôlez entièrement) est souvent la stratégie de déploiement la plus fiable.
Types de payload : ce qui se compresse bien (et ce qui ne l'est pas)
Les gains de compression ne dépendent pas seulement de l'algorithme. Le principal pilote est le type de données que vous envoyez. Certains payloads rétrécissent fortement avec ZSTD, Brotli ou GZIP ; d'autres à peine et ne font que brûler du CPU.
Excellents candidats (gains élevés)
Les réponses riches en texte se compressent extrêmement bien parce qu'elles contiennent des clés répétées, des espaces et des motifs prévisibles.
- JSON (y compris les réponses REST typiques)
- GraphQL (souvent verbeux avec des noms de champs répétés)
- XML et HTML
- Gros logs texte et traces d'erreur renvoyées par les APIs
Plus il y a de répétition et de structure, meilleur est le ratio.
Payloads binaires : “peut-être” (mesurez d'abord)
Les formats binaires comme Protocol Buffers et MessagePack sont plus compacts que JSON, mais ne sont pas « aléatoires ». Ils peuvent contenir des tags répétés, des layouts de records similaires et des séquences prévisibles.
Ils sont souvent encore compressibles, en particulier pour des réponses larges ou des endpoints renvoyant des listes. La seule réponse fiable est de tester avec votre trafic réel : même endpoint, mêmes données, compression activée/désactivée, et comparez taille et latence.
Généralement inutile (déjà compressé)
Beaucoup de formats sont déjà compressés en interne. Appliquer une compression HTTP dessus donne des gains minimes et peut augmenter le temps de réponse.
- Images : JPEG, PNG, WebP
- Vidéo/audio : MP4 (et similaires)
- Archives : ZIP, gzip
- PDF : souvent déjà compressé
Pour ces formats, il est courant de désactiver la compression selon le type de contenu.
Heuristiques pratiques (restez simples)
Une approche simple est de compresser seulement quand les réponses dépassent une taille minimale :
- Définissez un seuil de taille de réponse (par exemple, quelques Ko) avant d'activer
Content-Encoding. - Compressez toujours les grosses réponses textuelles ; sautez la compression pour les petits JSON où les en-têtes dominent.
Cela concentre le CPU sur les payloads où la compression réduit réellement la bande passante et améliore la performance bout en bout.
En-têtes HTTP et négociation : bien faire les choses
La compression ne fonctionne bien que lorsque clients et serveurs s'accordent sur un encodage. Cet accord se fait via Accept-Encoding (envoyé par le client) et Content-Encoding (renvoyé par le serveur).
Accept-Encoding et Content-Encoding (exemples simples)
Un client annonce ce qu'il peut décoder :
GET /v1/orders HTTP/1.1
Host: api.example
Accept-Encoding: zstd, br, gzip
Le serveur choisit un encodage et le déclare :
HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: zstd
Si le client envoie Accept-Encoding: gzip et que vous répondez Content-Encoding: br, ce client risque d'échouer à parser le corps. Si le client n'envoie pas Accept-Encoding, le plus sûr est de ne pas compresser.
Ordre de priorité côté serveur
Un ordre pratique pour les APIs est souvent :
zstdd'abord (bon équilibre vitesse/ratio)- puis
br(souvent plus petit, parfois plus lent) - puis
gzip(compatibilité maximale)
Autrement dit : zstd > br > gzip.
Ne considérez pas cela comme universel : si votre trafic est majoritairement navigateur, br peut mériter une priorité plus élevée ; si vous avez des clients mobiles anciens, gzip peut être le choix le plus sûr.
Vary: Accept-Encoding et le caching
Si une réponse peut être servie avec plusieurs encodages, ajoutez :
Vary: Accept-Encoding
Sans cela, un CDN ou proxy peut mettre en cache la variante gzip (ou zstd) et la servir incorrectement à un client qui n'a pas demandé (ou ne peut pas décoder) cet encodage.
Cas limites et fallbacks sûrs
Certains clients annoncent le support mais ont des décodeurs bogués. Pour rester résilient :
- Préférez un fallback connu : si les erreurs de décodage montent pour
zstd, rebasculer temporairement surgzip. - Envisagez des allowlists pour certains user agents ou versions d'SDK problématiques.
- Pour les endpoints critiques (auth, webhooks), envisagez de désactiver la compression ou d'utiliser uniquement l'option la plus compatible.
La négociation vise moins à gagner chaque octet qu'à ne jamais casser un client.
HTTP/2, HTTP/3, CDNs et gateways
La compression d'API ne fonctionne pas en vase clos. Le protocole de transport, la surcharge TLS et tout CDN ou gateway entre les deux peuvent changer le résultat réel — voire casser les choses si mal configurés.
HTTP/2 et HTTP/3 : multiplexage, head-of-line et impact de la compression
Avec HTTP/2, plusieurs requêtes partagent une connexion TCP unique. Cela réduit les coûts de connexion, mais la perte de paquets peut bloquer tous les streams à cause du head-of-line TCP. La compression aide en réduisant la quantité de données « bloquée » derrière un événement de perte.
HTTP/3 utilise QUIC (UDP) et évite le head-of-line TCP entre streams. La taille du payload reste importante, mais la pénalité de perte est souvent moins dramatique par connexion. En pratique, la compression reste utile — attendez-vous à des bénéfices davantage sur les économies de bande passante et le “time to last byte” que sur des baisses spectaculaires de latence.
TLS : ne négligez pas le budget CPU
TLS consomme déjà du CPU (handshakes, chiffrage/déchiffrage). Ajouter la compression (surtout à des niveaux élevés) peut vous faire franchir vos limites CPU lors de pics. C'est pourquoi des réglages de compression rapides avec un bon ratio surpassent souvent les réglages « maximum ratio » en production.
CDNs et API gateways : auto-compress, passthrough ou strip
Certains CDNs/gateways compressent automatiquement certains MIME types, d'autres font passer ce que l'origine envoie. Quelques-uns peuvent normaliser ou même supprimer Content-Encoding si mal configurés.
Vérifiez le comportement par route, et assurez-vous que Vary: Accept-Encoding est préservé pour que les caches ne servent pas une variante compressée à un client qui n'en a pas la capacité.
Stratégie de cache : edge vs origin (et variantes multiples)
Si vous mettez en cache en périphérie, envisagez de stocker des variantes séparées par encodage (gzip/br/zstd) plutôt que de recomprimer à chaque hit. Si vous cachez à l'origine, laissez le edge négocier et mettre en cache plusieurs encodages.
La clé est la cohérence : Content-Encoding correct, Vary correct et une responsabilité claire de qui compresse où.
Valeurs par défaut recommandées et playbook d'ajustement
Valeurs par défaut suggérées par scénario
Pour APIs orientées navigateur, préférez Brotli lorsque le client l'annonce (Accept-Encoding: br). Les navigateurs décodent généralement Brotli efficacement et il réduit souvent la taille sur les réponses textuelles.
Pour APIs internes service-à-service, par défaut ZSTD quand les deux côtés sont sous votre contrôle. Il est typiquement plus rapide pour un ratio égal ou meilleur que GZIP, et la négociation est simple.
Pour APIs publiques utilisées par des SDK variés, gardez GZIP comme baseline universelle et ajoutez ZSTD en opt-in pour les clients qui le supportent explicitement. Ainsi vous évitez de casser des piles HTTP anciennes.
Niveaux conservateurs de départ
Commencez par des niveaux faciles à mesurer et qui ne surprennent pas :
- Brotli : niveau 4–6 pour les réponses API dynamiques (les niveaux plus hauts peuvent ajouter du CPU notable)
- ZSTD : niveau 3–5 pour des payloads API généraux
- GZIP : niveau 5–6 comme bon compromis
Si vous avez besoin d'un meilleur ratio, validez avec des échantillons de payloads proches de la production et suivez la p95/p99 avant d'augmenter les niveaux.
Seuils de taille minimum (et réglage)
Compresser de petites réponses peut coûter plus de CPU que ça ne rapporte. Un point de départ pratique :
- Ne compressez pas en dessous de 1–2 Ko pour la plupart des APIs
- Envisagez 4 Ko si vous êtes lié par le CPU ou si les réponses sont très bavardes
Ajustez en comparant : (1) octets économisés, (2) temps serveur ajouté, (3) changement de latence bout en bout.
Manières sûres d'exposer le contrôle
Déployez la compression derrière un feature flag, puis ajoutez une config par route (activer pour /v1/search, désactiver pour endpoints déjà petits). Fournissez un opt-out client via Accept-Encoding: identity pour le dépannage et les clients limites. Incluez toujours Vary: Accept-Encoding pour garder les caches corrects.
Où cela intervient dans les workflows modernes
Si vous générez des APIs rapidement (par ex. prototypes full‑stack rapides), la compression devient un de ces petits réglages à fort impact. Sur Koder.ai, les équipes atteignent souvent ce point tôt car elles prototypent et déploient vite, puis règlent le comportement en production (compression des réponses, headers de cache) une fois les endpoints stabilisés. Le message pratique : considérez la compression comme une fonctionnalité de performance, activez-la derrière un flag et mesurez la p95/p99 avant de déclarer la victoire.
Déploiement, monitoring et dépannage
Les changements de compression sont faciles à déployer et étonnamment faciles à casser. Traitez-les comme une feature en production : déployez progressivement, mesurez l'impact et gardez un rollback simple.
Plan de déploiement sûr
Commencez par un canary : activez le nouvel Content-Encoding (par exemple zstd) pour une petite fraction du trafic ou un client interne.
Puis montez en charge (1 % → 5 % → 25 % → 100 %), en vous arrêtant si les métriques clés bougent mal.
Préparez un rollback facile :
- Un flag pour désactiver la compression (ou retomber sur
gzip). - Un moyen d'exclure des endpoints spécifiques (téléchargements, médias déjà compressés).
- Une modification de config rapide, pas un déploiement de code.
Ce qu'il faut surveiller (et pourquoi)
Traquez la compression à la fois comme changement de performance et de fiabilité :
- CPU (serveur et, si possible, client) : niveaux plus hauts peuvent faire monter le CPU.
- Latence percentiles (p50/p95/p99) : la compression aide souvent la moyenne mais peut nuire à la queue.
- Tailles de réponse : octets sur le fil par endpoint, et delta compressé vs non compressé.
- Taux d'erreur : surveillez
4xx/5xx, échecs de décodage client et timeouts.
Checklist de dépannage
Quand quelque chose casse, voici les suspects habituels :
- Double compression : l'origine compresse et la gateway/CDN compresse encore
- En-têtes erronés :
Content-Encodingindiqué mais le corps n'est pas compressé (ou inversement) - Mauvaise négociation : on ignore
Accept-Encodingou on renvoie un encodage que le client n'a pas annoncé - Flux corrompus : corps tronqué,
Content-Lengthincorrect ou interférence proxy/CDN
Documenter les attentes côté client
Indiquez clairement les encodages supportés dans votre doc :
- Ce que les clients doivent envoyer :
Accept-Encoding: zstd, br, gzip - Ce qu'ils recevront :
Content-Encoding: zstd(ou fallback)
Si vous fournissez des SDKs, ajoutez des exemples de décodage copy-pasteables et précisez les versions minimales pour Brotli ou Zstandard.
FAQ
Quand vaut-il vraiment la peine d'activer la compression des réponses API ?
Utilisez la compression de réponse lorsque les réponses sont riches en texte (JSON/GraphQL/XML/HTML), de taille moyenne à grande, et que vos utilisateurs sont sur des réseaux lents/ouverts à coût élevé ou que vous payez des frais d'egress significatifs. Évitez-la (ou appliquez un seuil élevé) pour les très petites réponses, les médias déjà compressés (JPEG/MP4/ZIP/PDF) et les services liés au CPU où un travail par requête supplémentaire détériorerait le p95/p99.
Pourquoi la compression peut-elle rendre une API plus lente alors que les réponses sont plus petites ?
Parce que la compression échange de la bande passante contre du CPU (et parfois de la mémoire). Le temps de compression peut retarder le début de l'envoi des octets (TTFB), et sous charge il peut amplifier l'enfilage des requêtes — affectant souvent la latence de queue (tail) même si la latence moyenne s'améliore. Le meilleur réglage est celui qui réduit le temps de bout en bout, pas seulement la taille utile.
Comment choisir entre ZSTD, Brotli et GZIP ?
Un ordre pratique par défaut pour beaucoup d'APIs :
zstden priorité (rapide, bon ratio)- puis
br(souvent le plus petit pour le texte, peut coûter plus de CPU) - puis
gzip(compatibilité maximale)
Basez toujours le choix final sur ce que le client annonce dans Accept-Encoding, et gardez un repli sûr (typiquement gzip ou identity).
Quels niveaux de compression sont des valeurs par défaut sensées pour des réponses API dynamiques ?
Commencez bas et mesurez.
- ZSTD : niveau 1–3 (ou jusqu'à 3–5) pour la plupart des APIs JSON dynamiques
- Brotli : niveau 1–4 pour la compression à la volée ; réservez 8–11 au contenu précompressé/statique
- GZIP : niveau 5–6 comme bon défaut
Les niveaux supérieurs offrent généralement des gains de taille décroissants mais peuvent crever le CPU et détériorer le p95/p99.
Faut-il compresser chaque réponse ou seulement au-dessus d'une certaine taille ?
Utilisez un seuil minimum de taille de réponse pour ne pas brûler du CPU sur des petits payloads.
- Point de départ typique : 1–2 Ko
- Si vous êtes lié par le CPU ou très bavard : envisagez 4 Ko
Réglez par endpoint en comparant les octets économisés, le temps serveur ajouté et l'impact sur la latence p50/p95/p99.
Quels types de payload se compressent bien (et lesquels généralement pas) ?
Concentrez-vous sur les types de contenu structurés et répétitifs :
- Excellents : JSON, GraphQL, XML, HTML, gros logs texte
- “Peut-être” : Protobuf/MessagePack (souvent compressibles — mesurer)
- Généralement inutile : JPEG/PNG/WebP, MP4, ZIP/gz, de nombreux PDF
Une approche courante consiste à activer la compression uniquement pour des valeurs Content-Type textuelles et à la désactiver pour les formats déjà compressés.
Comment fonctionnent Accept-Encoding et Content-Encoding pour les APIs ?
La négociation doit suivre HTTP :
- Le client envoie
Accept-Encoding(ex.zstd, br, gzip) - Le serveur répond avec un
Content-Encodingqu'il sait que le client peut décoder
Si le client n'envoie pas Accept-Encoding, la réponse la plus sûre est généralement sans compression. Ne renvoyez jamais un Content-Encoding que le client n'a pas annoncé, sinon il risque d'échouer à parser le corps.
Pourquoi `Vary: Accept-Encoding` est-il important lors de l'utilisation de la compression ?
Ajoutez :
Vary: Accept-Encoding
Cela empêche un CDN/proxy de mettre en cache (par exemple) une réponse gzip et de la renvoyer à un client qui n'a pas demandé ou ne peut pas décoder gzip (ou zstd/br). Si vous supportez plusieurs encodages, cet en-tête est essentiel pour un bon comportement du cache.
Quels sont les bugs de compression les plus courants en production ?
Les modes d'échec fréquents incluent :
- Double compression (l'origine compresse, puis la passerelle/CDN compresse à nouveau)
- Incohérence en-têtes/corps (
Content-Encodingindique gzip mais le corps n'est pas gzippé) - Mauvaise négociation (ignorer
Accept-Encoding) - Interférence proxy/CDN (suppression ou altération d'en-têtes)
Content-Lengthincorrect lors du streaming/compression
Pour déboguer, capturez les en-têtes bruts et vérifiez la décompression avec un client/outils de référence.
Comment déployer et surveiller la compression API en toute sécurité ?
Déployez-le comme une fonctionnalité de performance :
- Canary : activez le nouvel
Content-Encoding(par ex.zstd) pour une petite portion du trafic - Rampa progressivement (1 % → 5 % → 25 % → 50 % → 100 %), en arrêtant si les métriques se dégradent
- Prévoyez un rollback rapide (flag de fonctionnalité ou config de passerelle)
Surveillez :
- CPU (utilisation/saturation)
- Latence p50/p95/p99 et TTFB
- octets sur le fil (compressés vs non compressés)
- erreurs/timeouts et échecs de décodage côté client
Si la latence tail augmente sous charge, baissez le niveau, augmentez le seuil, ou passez à un codec plus rapide (souvent ZSTD).