Le codec HTTP/2 de Google coûte 20 % de débit à Envoy — la régression que personne n’avait profilée
L’équipe d’Apoxy a mesuré une perte de 20 % de débit HTTP/2 par cœur après le passage d’Envoy au codec oghttp2 de Google. L’enquête pointe la couche de bookkeeping au-dessus du décodeur Huffman, pas le décodeur lui-même.
4 août 2026. Dmitry Ilyevsky, cofondateur et CTO d’Apoxy, publie une enquête de performance qui fera date dans l’écosystème Envoy. Une simple montée de version — un bump de routine — a coûté 20 % de débit HTTP/2 à un client. La cause n’était ni le trafic, ni la configuration, mais le codec HTTP/2 par défaut qu’Envoy a changé en version 1.34.
Envoy v1.34 a basculé de nghttp2 vers oghttp2, le codec C++ de Google issu de la famille QUICHE. La régression a été confirmée par plusieurs utilisateurs. Envoy v1.37.0 a fait marche arrière, rétablissant nghttp2 comme défaut. Mais l’équipe d’Apoxy ne s’est pas arrêtée là. Elle a profilé les deux codecs sur quatre microarchitectures et publié les flamegraphs. Ce que l’enquête révèle change notre compréhension de la performance des proxies HTTP/2.
Le problème n’est pas le décodeur Huffman
L’intuition initiale pointait le décodeur Huffman de oghttp2. HPACK (RFC 7541) compresse les en-têtes HTTP/2 avec un code de Huffman canonique figé dans la RFC depuis une décennie. Chaque requête qui traverse un proxy doit être décodée et ré-encodée — des centaines de milliers d’opérations par seconde par cœur sur un proxy edge. Si le décodeur est lent, le proxy s’effondre.
nghttp2 utilise depuis 2014 une machine à états finis précalculée pour le décodage Huffman. Avec des chunks de 4 bits, la table d’état fait 16 Kio — elle tient dans le cache L1. Deux lookups par octet d’entrée, aucune branche conditionnelle. C’est du génie logiciel discret, et ça profile à plat.
L’équipe s’attendait donc à trouver le problème dans le kernel Huffman de QUICHE. Les flamegraphs ont dit non. Le décodeur de oghttp2 est plus lent, certes, mais l’essentiel de la différence se situe au-dessus : la classe HttpHeaderBlock et les couches de représentation et de comptabilité que chaque en-tête décodé traverse. Ce surcoût est de 20 à 30 µs par requête, constant, sur tous les hôtes mesurés.
Quatre architectures, un verdict
Les benchmarks ont été exécutés sur Intel Sapphire Rapids, AMD Zen 4, AWS Graviton4 et Google Axion. Le protocole est reproductible : h2load → Envoy → backend Go h2c en loopback sur le même hôte, chaque processus épinglé à des cœurs physiques disjoints, Envoy à --concurrency 1. Le RPS/cœur mesure l’efficacité CPU pure.
nghttp2 bat oghttp2 de 15 à 25 % en RPS/cœur sur le trafic proxy réel (riche en en-têtes), 7 à 19 % sous fort churn de connexions. La régression est réelle, portable, et ne dépend pas du silicium.
Un détail important : si vous compilez Envoy vous-même, vérifiez vos flags d’optimisation. Le .bazelrc d’Envoy ne définit pas -c opt par défaut. Un bazel build nu produit un binaire fastbuild (debug) qui benchmark 15 à 32× plus lent que le même code en -c opt. L’équipe d’Apoxy l’a découvert à ses dépens.
Ce que ça change pour les opérateurs de proxy
Le correctif immédiat est simple : rester sur nghttp2. Envoy v1.37.0 en a refait le défaut, et un commentaire dans le source promet de réessayer « quand la performance s’alignera sur nghttp2 ». Mais l’enquête d’Apoxy met le doigt sur un problème plus profond.
oghttp2 partage du code avec la pile HTTP/3 d’Envoy. C’est un argument d’unification : un seul codec pour HTTP/2 et HTTP/3, une surface de maintenance réduite, moins de bugs de divergence. La régression mesurée montre que l’unification a un coût, et que ce coût n’est pas dans l’algorithme — il est dans l’architecture logicielle qui enveloppe l’algorithme.
Pour les opérateurs de proxy qui traitent des dizaines de milliers de requêtes par seconde par cœur, 20 % de débit en moins, c’est 20 % de serveurs en plus. Le choix du codec n’est pas un détail d’implémentation — c’est un poste de coût infrastructure.
Verdict
Si vous exécutez Envoy en production aujourd’hui, restez sur nghttp2. La bascule vers oghttp2 n’apporte aucun bénéfice mesurable et coûte du débit. Si vous êtes sur une version ≥ 1.34 et que vous n’avez pas explicitement choisi le codec, vérifiez votre configuration : la régression est silencieuse — vos graphs CPU montent, c’est tout.
L’enquête d’Apoxy se termine sur une promesse : un deuxième article où ils rendent le codec rapide encore plus rapide. D’ici là, le verdict est sans appel. nghttp2 est le codec de production pour Envoy.
Références
- Apoxy Blog, « A Tale of Two HTTP/2 Codecs », 4 août 2026 — https://apoxy.dev/blog/oghttp2-vs-nghttp2
- Envoy GitHub, Issue #37429, « http2: switch default codec back to nghttp2 », v1.37.0 — https://github.com/envoyproxy/envoy
- RFC 7541, « HPACK: Header Compression for HTTP/2 », mai 2015 — https://datatracker.ietf.org/doc/html/rfc7541