Trois versions,
un seul langage
HTTP/1.1, HTTP/2, HTTP/3 : ce ne sont pas trois protocoles rivaux, mais trois façons de faire voyager la même conversation. Ce qui change est dessous : le transport.
Quand tu tapes une URL, ton navigateur et le serveur se parlent en HTTP : « donne-moi cette page » (GET), « voici, tout va bien » (200), avec des en-têtes autour. Ce vocabulaire n'a quasiment pas bougé depuis 1997. Ce qui a profondément changé en trente ans, c'est la plomberie qui transporte ces messages — et c'est elle qui sépare 1.1, 2 et 3.
Ce cours suit cette évolution comme une enquête : à chaque version, on identifie le problème de performance qui restait, et la solution apportée. Tu verras que chaque version résout le goulot d'étranglement de la précédente… et en révèle un nouveau, plus subtil.
Le chemin d'une page
La frise en une ligne
| Version | Année | Transport | Idée maîtresse |
|---|---|---|---|
| HTTP/1.1 | 1997 | TCP, texte | connexions persistantes — mais une réponse à la fois |
| HTTP/2 | 2015 | TCP, binaire | multiplexage : tout dans une seule connexion |
| HTTP/3 | 2022 | QUIC (UDP) | changer de transport pour tuer le blocage TCP |
Repères de standardisation : HTTP/2 = RFC 7540 (2015), refondu en RFC 9113 ; HTTP/3 = RFC 9114 (juin 2022), au-dessus de QUIC = RFC 9000/9001/9002 (mai 2021).
Par où commencer
Sémantique vs transport
Si tu ne retiens qu'une chose de ce cours, que ce soit celle-ci : HTTP est resté le même, on a seulement changé le véhicule qui le porte.
GET, POST…), les codes de statut (200, 404, 500…), les en-têtes (Content-Type, Cookie…). Cette couche est identique en HTTP/1.1, 2 et 3.Cette distinction est le fil conducteur du cours entier. Elle te dit exactement où regarder quand quelque chose cloche. Un 404 inattendu ou un bug d'authentification, c'est de la sémantique — cherche dans ton code ou ta config applicative. Un téléchargement qui plafonne sur un réseau dégradé ou se fige sur mobile, c'est du transport — regarde ta version HTTP, ton CDN, la qualité du réseau. Les deux couches ont des diagnostics différents, des outils différents et des profils de bugs différents.
L'image : la sémantique HTTP est la langue que parlent le client et le serveur — les mots « je veux cette page » / « voici, tout va bien ». Le transport est le mode d'acheminement de ces phrases : un coursier à vélo qui livre un colis à la fois et revient chercher le suivant (HTTP/1.1), un coursier qui porte plusieurs colis d'un coup et les livre en parallèle (HTTP/2 multiplexé), ou un coursier en scooter sur une voie séparée dont chaque colis avance indépendamment des autres (HTTP/3 sur QUIC). On change de coursier ; la langue reste exactement la même.
GET /produit/42 avec ses en-têtes, quelle que soit la version négociée. Passer de HTTP/1.1 à HTTP/3 est un changement d'infrastructure (serveur, reverse proxy, CDN) — pas de code métier. C'est précisément ce découplage qui a permis de réinventer le transport plusieurs fois sans casser le web existant.Les deux transports en jeu
| TCP | QUIC | |
|---|---|---|
| Utilisé par | HTTP/1.1 et HTTP/2 | HTTP/3 |
| Repose sur | lui-même (couche OS) | UDP + logique applicative |
| Livraison | flux ordonné global | flux indépendants par stream |
| Chiffrement | ajouté par-dessus (TLS) | intégré (TLS 1.3 inclus) |
| Blocage HOL | un paquet perdu gèle tout | isolé au stream concerné |
Garde les lignes « Livraison » et « Blocage HOL » en tête : c'est l'ordre global imposé par TCP qui provoque le piège de la section 05, et l'indépendance des streams QUIC qui l'élimine en sections 06–07. Tout le reste du cours développe ce tableau.
HTTP/1.1 & le blocage
Un protocole texte, lisible, robuste — et un défaut structurel : sur une connexion, on ne traite qu'une requête à la fois.
Ce que 1.1 a apporté
Avant, en HTTP/1.0, chaque requête ouvrait une connexion TCP, récupérait une ressource, puis fermait tout. Rouvrir une connexion pour chaque image d'une page était un gâchis. HTTP/1.1 a introduit les connexions persistantes (keep-alive) : on garde la connexion ouverte et on y enchaîne plusieurs requêtes.
Le défaut : une réponse à la fois
Sur une connexion HTTP/1.1, les requêtes sont traitées en série : la réponse 1 doit partir avant qu'on s'occupe de la 2. Il existe bien une option, le pipelining (envoyer plusieurs requêtes sans attendre), mais les réponses doivent revenir dans l'ordre d'envoi : une réponse lente bloque toutes celles derrière elle. Mal supporté et source de bugs, le pipelining est resté désactivé par défaut dans les navigateurs.
L'analogie : une caisse de supermarché qui sert un client à la fois. Si la personne en tête a un caddie immense, celle qui n'a qu'une bouteille d'eau attend quand même. C'est exactement la connexion HTTP/1.1.
La parade des navigateurs : ouvrir plusieurs caisses
Pour contourner ça, le navigateur ouvre plusieurs connexions en parallèle vers un même domaine — typiquement autour de 6 (ce n'est pas imposé par la norme, c'est une limite usuelle des navigateurs). Six caisses ouvertes, donc jusqu'à six téléchargements de front. Mais ça reste un pansement : au-delà de 6, ça fait la queue, et chaque connexion coûte (mémoire, établissement TCP + TLS).
Charge une petite page : 9 fichiers, dont un gros bundle JS en premier. Compare une seule connexion (tout en file) et six connexions parallèles.
📥 Téléchargement des ressourcest = 0
style.css attendre derrière le gros app.js : c'est le head-of-line blocking.HTTP/2 : le multiplexage
La grande idée de 2015 : arrêter d'ouvrir six connexions, et faire passer toutes les requêtes dans une seule — entremêlées.
Du texte au binaire
HTTP/1.1 envoie des messages en texte (lisibles à l'œil). HTTP/2 passe à un cadre binaire : les messages sont découpés en petits frames (trames) étiquetées, regroupées en streams (flux). C'est ce découpage qui rend le multiplexage possible.
L'analogie : au lieu de six caisses (six connexions HTTP/1.1), une seule caisse avec un tapis roulant qui mélange les articles de plusieurs clients. Comme chaque article porte une étiquette (l'ID de stream), on sait à qui il appartient. Plus besoin d'attendre qu'un client finisse pour servir le suivant : tout avance ensemble.
Même page (12 ressources) chargée des deux façons. À gauche, HTTP/1.1 plafonné à 6 connexions ; à droite, HTTP/2 qui pousse tout sur une connexion multiplexée.
🐌 HTTP/1.1 — 6 connexionst = 0
⚡ HTTP/2 — 1 connexion multiplexéet = 0
Autres apports de HTTP/2
HTTP/2 a aussi introduit la compression des en-têtes (HPACK) et la priorisation des streams (dire « ce CSS critique d'abord, cette image de pied de page ensuite »). On détaille HPACK — et le destin du défunt « Server Push » — à la fiche suivante.
En-têtes & Server Push
Deux fonctionnalités de HTTP/2 : l'une (la compression d'en-têtes) est un franc succès ; l'autre (le push) est aujourd'hui abandonnée.
HPACK : ne pas répéter ses en-têtes
À chaque requête, le navigateur renvoie une montagne d'en-têtes quasi identiques : le même User-Agent (souvent 80 à 150 octets), les mêmes cookies de session, le même Accept-Encoding… En HTTP/1.1, tout ça repart en entier à chaque fois, en texte clair. Sur une page à 80 ressources, c'est un gâchis répété — et particulièrement douloureux quand chaque requête inclut un cookie de session de 200 octets.
— Table statique : 61 entrées prédéfinies (méthodes courantes, codes de statut fréquents, en-têtes standard comme
content-type, cache-control, accept-encoding…), disponibles d'emblée sans aucun échange préalable.— Table dynamique : alimentée au fil des échanges. Une fois qu'un en-tête a été transmis, les messages suivants le référencent par un simple index entier au lieu de le réécrire. Les deux extrémités maintiennent une copie synchronisée de cette table.
L'image : la première fois, tu épelles ton adresse complète au livreur ; la fois d'après, tu dis juste « même adresse que tout à l'heure » et il retrouve seul. En pratique : un User-Agent de 120 octets passe à quelques octets (l'index dans la table) dès la deuxième requête. Sur 80 ressources avec ce même en-tête, c'est plus de 9 000 octets économisés rien que sur cet en-tête — multiplie par les cookies et la dizaine d'autres en-têtes répétitifs.
Server Push : l'idée séduisante… puis abandonnée
HTTP/2 permettait au serveur de pousser des ressources que le client n'avait pas encore demandées : « tu réclames index.html ? tiens, je t'envoie aussi style.css tout de suite, tu en auras besoin ». Sur le papier, un aller-retour gagné.
Le remplaçant recommandé est 103 Early Hints : une réponse intermédiaire où le serveur suggère au client de précharger certaines ressources (via des en-têtes Link: rel=preload), en le laissant décider — sans rien lui imposer ni gaspiller de bande passante si le fichier est déjà en cache.
<link rel=preload> dans le HTML et 103 Early Hints côté serveur — c'est la voie recommandée aujourd'hui.Le piège qui reste
HTTP/2 a supprimé le blocage au niveau HTTP. Mais en mettant tout sur une seule connexion TCP, il a fait remonter le même problème… un cran plus bas.
Le retour du head-of-line, version TCP
HTTP/2 entrelace plusieurs streams sur une connexion TCP. Or TCP a une règle d'or : il livre les octets strictement dans l'ordre où ils ont été envoyés. Si un paquet se perd en route, TCP retient tout ce qui arrive après dans un tampon, et ne le remet à l'application qu'une fois le paquet manquant retransmis.
L'analogie : un tapis roulant unique qui impose de livrer les colis dans l'ordre. Si le colis n°5 tombe, les colis 6, 7, 8 — même posés sur le tapis, même destinés à d'autres personnes — attendent qu'on ait remis le n°5. C'est absurde, mais c'est la garantie d'ordre de TCP.
Trois streams (A, B, C) envoient chacun 6 paquets, entrelacés sur la connexion. Un paquet du stream B se perd. Compare le comportement selon le transport.
Voilà le mur. On a beau optimiser HTTP au-dessus, le transport TCP impose son ordre global. Pour aller plus loin, il fallait changer de transport. C'est tout l'objet de HTTP/3.
QUIC : un nouveau transport
Plutôt que de réparer TCP (quasi impossible à faire évoluer), QUIC repart d'UDP et reconstruit un transport moderne par-dessus.
UDP. Il fournit ce que TCP offrait — fiabilité, contrôle de congestion — plus le multiplexage de streams indépendants et le chiffrement, le tout réuni dans un seul protocole évolutif.Pourquoi UDP ?
TCP est gravé dans le noyau des systèmes d'exploitation et dans d'innombrables équipements réseau intermédiaires (pare-feux, proxys, balanceurs de charge, boîtiers NAT — les « middleboxes »). Ces équipements ont, au fil du temps, appris à inspecter les paquets TCP, parfois à les modifier. Faire évoluer TCP demanderait de convaincre et de mettre à jour des millions de machines réparties sur l'internet — un chantier de plusieurs décennies.
UDP est l'opposé : il expédie des datagrammes sans ordre ni garantie. QUIC l'utilise comme base neutre, et reconstruit par-dessus — en espace utilisateur, dans la bibliothèque réseau de l'application, pas dans le noyau — tout ce que TCP offrait, plus ce qu'il ne pouvait pas offrir.
Streams vraiment indépendants
C'est la réponse directe au piège de la section 05. QUIC gère le multiplexage au niveau du transport : chaque stream est une séquence ordonnée à lui seul. Un paquet perdu n'affecte que le ou les streams dont il portait des données — les autres continuent d'être livrés intégralement.
Le chiffrement n'est pas une option
Là où TCP est neutre et où l'on ajoute TLS par-dessus, QUIC intègre TLS 1.3 dans le protocole. Il n'existe pas de QUIC « en clair » : tout est chiffré, en-têtes de transport compris. C'est la réponse directe à l'ossification — les middleboxes ne peuvent plus inspecter ce qu'elles ne savent pas lire. On verra en section 07 que cette fusion transport + chiffrement permet aussi d'établir une connexion en un seul aller-retour au lieu de deux.
HTTP/3 en pratique
Au-delà de la fin du blocage TCP, QUIC apporte deux atouts très concrets : une connexion qui s'établit plus vite, et qui survit aux changements de réseau.
Un handshake fusionné : moins d'allers-retours
Chaque aller-retour entre client et serveur (un RTT, round-trip time) coûte du temps, surtout sur mobile. En TCP, on paie d'abord le handshake TCP, puis le handshake TLS — deux négociations successives. QUIC les fusionne : transport et chiffrement se négocient ensemble.
Compte les allers-retours avant que la 1ʳᵉ donnée HTTP puisse partir, selon le scénario.
GET idempotents), jamais à un paiement. Et le décompte de RTT ci-dessus est volontairement simplifié.La migration de connexion
Tu télécharges un fichier en Wi-Fi, tu sors, ton téléphone bascule en 4G. En TCP, la connexion est identifiée par le quadruplet IP source : port → IP dest : port ; changer d'IP la casse, il faut tout recommencer. QUIC identifie la connexion par un Connection ID indépendant de l'adresse : la connexion te suit sur le nouveau réseau, sans coupure.
L'image : en TCP, ton identité est ton adresse postale — si tu déménages, on perd ta trace. En QUIC, tu as un badge nominatif que tu gardes quel que soit l'endroit d'où tu te connectes.
QPACK : HPACK adapté à QUIC
La compression d'en-têtes de HTTP/2 (HPACK) supposait une livraison ordonnée — exactement ce que QUIC n'offre plus entre streams. HTTP/3 utilise donc QPACK (RFC 9204), une variante conçue pour fonctionner même quand les en-têtes arrivent dans le désordre, sans réintroduire de blocage de tête de file.
Découverte & adoption
Comment un navigateur sait qu'un site parle HTTP/3 — et où en est réellement le déploiement, sans survente.
Le problème de l'amorçage
Une connexion commence forcément « à l'aveugle ». Le navigateur ne peut pas deviner que le serveur parle HTTP/3 : il se connecte d'abord classiquement (souvent en HTTP/2 sur TCP). Le serveur lui signale alors qu'il fait mieux ailleurs.
Alt-Svc (Alternative Services) est la pancarte du serveur : « je suis aussi joignable en HTTP/3 sur tel port ». Le navigateur le mémorise et tente HTTP/3 aux visites suivantes. Une alternative plus rapide existe via un enregistrement DNS dédié (type HTTPS/SVCB), qui annonce le support avant même la première connexion.Conséquence importante : beaucoup de premières visites ne passent jamais en HTTP/3 — elles se contentent du HTTP/2 négocié d'entrée. D'où un écart entre « le site sait faire du HTTP/3 » et « la connexion a réellement utilisé HTTP/3 ».
Où en est-on vraiment ? (mi-2026)
Les chiffres dépendent énormément de ce qu'on mesure. Deux angles à ne pas confondre :
| Mesure | Ordre de grandeur | Ce que ça veut dire |
|---|---|---|
| Part des requêtes sur le fil (Cloudflare Radar) | HTTP/2 ≈ 51 % · HTTP/1.x ≈ 28 % · HTTP/3 ≈ 21 % | Le trafic réellement échangé. HTTP/3 plafonne depuis plusieurs mois. |
| Part des sites qui « supportent » HTTP/3 (W3Techs) | ≈ 38–39 % | Sites qui annoncent HTTP/3 (via Alt-Svc), pas forcément utilisé. |
Pourquoi HTTP/1.1 ne meurt pas
Une part tenace du trafic reste en HTTP/1.1 : proxys d'entreprise et équipements réseau qui « rétrogradent » les connexions, vieux load balancers, API internes jamais migrées, bots et clients non-navigateurs. Le protocole de 1997 a la vie dure parce qu'il est simple et universellement supporté.
Synthèse
Le tableau de bord des trois versions, et le réflexe à garder pour chaque idée.
Comparatif des versions
| HTTP/1.1 | HTTP/2 | HTTP/3 | |
|---|---|---|---|
| Année | 1997 | 2015 | 2022 |
| Transport | TCP | TCP | QUIC (UDP) |
| Format | texte | binaire (frames) | binaire (frames) |
| Multiplexage | non | oui | oui |
| Blocage HTTP | oui | résolu | résolu |
| Blocage TCP | oui | oui (subsiste) | éliminé |
| Compression en-têtes | aucune | HPACK | QPACK |
| Établissement | ~2 RTT | ~2 RTT | 1 RTT, voire 0 |
| Chiffrement | TLS optionnel | TLS (navigateurs) | intégré |
| Migration réseau | non | non | oui |
Une phrase par concept
| Sémantique HTTP | Le sens des messages (méthodes, codes, en-têtes) ; identique partout. |
| Transport | Comment les messages voyagent ; c'est lui qui distingue 1.1 / 2 / 3. |
| Multiplexage | Plusieurs flux sur une connexion ; supprime le blocage au niveau HTTP. |
| Head-of-line blocking | Le premier de la file bloque les suivants, même prêts. |
| Blocage TCP | Un paquet perdu gèle tous les streams partageant la connexion TCP. |
| QUIC | Transport sur UDP : streams indépendants, chiffrement intégré, évolutif. |
| 0-RTT | Reprise instantanée d'une connexion connue (à réserver aux requêtes sûres). |
| Migration de connexion | La session QUIC survit au changement de réseau grâce au Connection ID. |
Guide de choix express
- Site web public en HTTPS → active HTTP/2 ; ajoute HTTP/3 si ton serveur/CDN le propose (gain net sur mobile, sinon neutre).
- API à fort débit, clients lointains ou mobiles → HTTP/3 vaut clairement le coup (0-RTT, pas de blocage TCP).
- Trafic interne fibré, faible latence → un bon HTTP/2 suffit largement ; HTTP/3 apporte peu.
- Compatibilité maximale / vieux clients → garde HTTP/1.1 en repli ; il reste le dénominateur commun.