ITの教科書検索
入門・発展ページ読了 約11分

HTTP/3とQUICとは ― HTTP/2との違いとUDPを使う理由

HTTP/3はUDP上のQUICで動くHTTPです。HTTP/2との違い、UDPを使う理由、有効にするときの注意、h3と出ているかの確かめ方が分かります。

目次
  1. HTTP/3とは
  2. HTTP/1.1・HTTP/2との違い
  3. HTTP/2に残った課題
  4. QUICとは
  5. 接続が速い理由と0-RTT
  6. 回線が切り替わっても続く
  7. 有効にするときの注意
  8. 使われているか確かめる
  9. 練習問題

HTTP/3とは、TCPの代わりにQUICで運ぶ新しいHTTP

HTTP/3は、TCPの代わりにQUICを使うHTTPの新しい版です。QUICはUDPの上で動き、接続の管理と再送と暗号化をまとめて受け持ちます。

ブラウザの開発者ツールのプロトコル列にh3と出ていれば、その通信はHTTP/3です。CDNの設定画面にある「HTTP/3を有効にする」のスイッチも、ファイアウォールでUDP 443を開ける依頼も、この通信のためのものです。

変わるのは運び方だけで、URLやGET、200のようなHTTPの決まりはそのまま使えます。接続の準備が1往復減り、パケットが1つ失われても、ほかのファイルの受信が止まりにくくなります。HTTP/2との違い、UDPを使う理由、有効にするときの注意、確かめ方の順に説明します。

HTTP/1.1・HTTP/2・HTTP/3の違い:変わったのは下の層

3つの版は、リクエストとレスポンスの意味が同じで、データの運び方が違います。HTTP/1.1とHTTP/2はTCPの上で動き、HTTP/3だけがQUICの上で動きます。基本のやり取りは、HTTPとHTTPSの記事で確かめられます。

HTTP/1.1TLS暗号化TCP再送・順序IPHTTP/2ストリームTLS暗号化TCP再送・順序IPHTTP/3QUIC暗号化再送・順序ストリームUDPIP
HTTP/3では、暗号化と再送とストリームをQUICが1つの層でまとめて受け持ちます。UDPは、パケットを運ぶだけです。

HTTP/2は、1本の接続の中に複数のストリームを作ります。ストリームは、リクエストとレスポンスを1組ずつ運ぶ独立した通り道です。HTTP/3では、このストリームと、TLSの暗号化と、TCPの再送をQUICが1つにまとめています。

HTTP/1.1HTTP/2HTTP/3
下で動くプロトコルTCPTCPUDPの上のQUIC
暗号化TLSを足してHTTPSにする主にTLSと組み合わせるQUICに組み込み。平文では使えない
同時のやり取りTCP接続を複数張って並行する1本のTCP接続で並行する1本のQUIC接続で並行する
パケットが失われたときその接続のやり取りが待つその接続の全部のやり取りが待つ失われたストリームだけが待つ
ヘッダの形文字列のままバイナリ。HPACKで圧縮バイナリ。QPACKで圧縮
プロトコル列の表示http/1.1h2h3
規格RFC 9112RFC 9113RFC 9114

ヘッダの圧縮方式が違うのは、順番の扱いが変わったからです。HTTP/2のHPACKは、圧縮したヘッダが順番どおりに届くことを前提にしています。QUICはストリームどうしの順番を保証しないので、HTTP/3はQPACKに置き換えました。

HTTP/2に残った課題:1つのパケット損失で全部が待つ

HTTP/2は、1本のTCP接続の中でHTMLとCSSと画像を同時に運びます。ところがTCPから見ると、中身はストリームの区別がない1列のデータです。TCPはパケットが1つ欠けると、再送が届くまで後ろのデータをアプリへ渡しません。

欠けたのが画像のパケットでも、HTMLやCSSまで待たされます。列の先頭が詰まると後ろが進めないので、この状態をヘッドオブラインブロッキングと呼びます。

HTTP/2は、HTTP/1.1で前のレスポンスを待っていた、HTTPの層の順番待ちをストリームでなくしました。それでもTCPの層の順番待ちは残り、HTTP/2の規格にも、この問題は解決していないと書かれています。

QUICは、データの順序をストリームごとに管理します。欠けたパケットのストリームだけが待ち、ほかのストリームは受け取りを続けます。次の例は、3つのファイルを6個のパケットで交互に運んだ場合です。

失われるパケットを選ぶ

HTTP/2(TCP):6個のうち2個をアプリへ渡せる

  1. 1HTML渡す
  2. 2CSS渡す
  3. 3画像失う
  4. 4HTML待つ
  5. 5CSS待つ
  6. 6画像待つ

HTTP/3(QUIC):6個のうち4個をアプリへ渡せる

  1. 1HTML渡す
  2. 2CSS渡す
  3. 3画像失う
  4. 4HTML渡す
  5. 5CSS渡す
  6. 6画像待つ

3番の画像が再送されるまで、HTTP/2では後ろの3個がすべて待ちます。HTTP/3で待つのは、画像の6番だけです。

この例は、1つのパケットに1つのファイルのデータだけが入る前提です。1つのパケットに複数のストリームのデータが入っていれば、そのストリームはどれも待ちます。送る速さの調整は接続全体で行うので、損失が続けば全体の速度も落ちます。

QUICとは:UDPの上に接続・再送・暗号化を載せたプロトコル

HTTP/3とQUICの違いは、受け持つ層です。QUICはデータを運ぶトランスポート層のプロトコルで、HTTP/3はその上でリクエストとレスポンスをやり取りする決まりです。QUICはHTTP専用ではなく、DNSの問い合わせを運ぶ規格もあります。

なぜTCPを直さずUDPを使うのか

UDPそのものは、再送も順序の管理もしません。QUICはその機能を自分で持ち、UDPにはパケットを運ぶことだけを任せます。

UDPを選んだ理由は2つあります。1つは、NATなどの経路上の機器を更新しなくても通せることです。もう1つは、OSの中ではなくアプリの側でプロトコルを実装できることです。TCPを直すには各OSの更新が要りますが、QUICならブラウザやサーバのソフトを更新するだけで変えられます。

TLS 1.3はQUICの中に組み込まれている

TCPでは、TLSがTCPの上に別の層として載ります。QUICでは、TLS 1.3の手順で鍵を決め、その鍵でQUIC自身がパケットを暗号化します。TLSのレコードは使いません。鍵を決める手順そのものは、SSL/TLSの記事で追えます。

TLS 1.2以下には戻せません。QUICのクライアントは、1.3より古いTLSを提案してはならないからです。そのためHTTP/3には平文の通信がなく、http://のURLに直接使うこともできません。

暗号化する範囲も広くなりました。TCPでは、シーケンス番号やACK番号が経路上から読めます。QUICでは、パケット番号やACKの情報まで暗号化します。ただし、接続の最初のパケットは経路上の機器でも解読できる鍵で保護するだけなので、宛先のサイト名などは読めます。

接続が速い理由:最初は1往復、再接続は0往復にもできる

TCPの上のHTTPSは、TCPの準備に1往復、TLS 1.3の準備に1往復かかります。QUICは、接続の準備と暗号の準備を同じ1往復で済ませます。リクエストを送れるまでの時間が、1往復分短くなります。

TCP+TLS 1.3:送るまで2往復クライアントサーバ1往復目2往復目3往復目SYNSYN+ACKACK・ClientHelloServerHello・証明書Finished・リクエストレスポンスQUIC:送るまで1往復クライアントサーバ1往復目2往復目ClientHelloServerHello・証明書Finished・リクエストレスポンスQUICの0-RTT:すぐ送れるクライアントサーバ1往復目ClientHelloリクエストServerHelloレスポンスTCP+TLS 1.3:送るまで2往復クライアントサーバ1往復目2往復目3往復目SYNSYN+ACKACK・ClientHelloServerHello・証明書Finished・リクエストレスポンスQUIC:送るまで1往復クライアントサーバ1往復目2往復目ClientHelloServerHello・証明書Finished・リクエストレスポンスQUICの0-RTT:すぐ送れるクライアントサーバ1往復目ClientHelloリクエストServerHelloレスポンス
色の付いた矢印が、リクエストを送る時点です。QUICは、接続と暗号の準備を1往復にまとめます。図は主なメッセージだけを描いています。

往復に50ミリ秒かかる回線なら、TCPとTLS 1.3では100ミリ秒後、QUICでは50ミリ秒後にリクエストを送れます。この差が出るのは新しい接続を作るときで、接続を使い続けている間は差がありません。最初のパケットが失われたときや、サーバがRetryで送信元を確かめるときは、もう少しかかります。

0-RTT:前に接続した相手なら最初の送信でリクエストを送れる

クライアントが前回の接続の情報を覚えていれば、最初のパケットと一緒にリクエストを送れます。準備の往復を待たないので、この方法を0-RTTと呼びます。RTTは往復にかかる時間のことです。サーバが対応している必要があり、前回の接続から7日以内という上限もあります。

0-RTTには、リプレイ攻撃のおそれがあります。経路上の第三者が記録したパケットを送り直すと、サーバが同じリクエストを2回処理することがあるのです。ページの取得なら影響は小さくても、注文の確定が2回動くと困ります。

そのためRFC 8470は、ほかに情報がなければ、0-RTTで送れるのはGETのような安全なメソッドに限ると定めています。サーバは、処理したくないリクエストを425 Too Earlyで断れます。TLS 1.3にも0-RTTはありますが、TCPの上ではTCPの準備の1往復が残ります。

回線が切り替わっても続く:コネクションIDの仕組み

TCPの接続は、双方のIPアドレスとポート番号の組で決まります。スマホがWi-Fiからモバイル回線に切り替わると、送信元のIPアドレスが変わります。TCPは同じ接続を続けられないので、アプリは接続を作り直します。

QUICは、接続をコネクションIDで見分けます。送信元のアドレスが変わっても、サーバはこのIDから同じ接続だと分かります。接続を保ったまま経路を移すこの動きを、コネクションマイグレーションと呼びます。

TCP:接続し直すサーバ切り替えWi-Fi送信元 198.51.100.5IPアドレスで見分けるモバイル送信元 198.51.100.77別の接続に見える同じ接続を続けられないQUIC:同じ接続が続くサーバ切り替えWi-Fi送信元 198.51.100.5コネクションID Aモバイル送信元 198.51.100.77コネクションID B同じ接続のIDだと分かるTCP:接続し直すサーバ切り替えWi-Fi送信元 198.51.100.5IPアドレスで見分けるモバイル送信元 198.51.100.77別の接続に見える同じ接続を続けられないQUIC:同じ接続が続くサーバ切り替えWi-Fi送信元 198.51.100.5コネクションID Aモバイル送信元 198.51.100.77コネクションID B同じ接続のIDだと分かる
TCPは送信元のIPアドレスが変わると別の接続になります。QUICは新しい回線で別のIDに替えますが、サーバは同じ接続のIDだと分かります。

新しい回線では、IDもAからBに替えます。同じIDを使い続けると、経路上の第三者に、2つの回線の通信を同じ人のものと結び付けられるからです。クライアントは別のIDをあらかじめ受け取っておくので、サーバ側では同じ接続のままです。

ただし、切り替えの間も通信がまったく止まらないわけではありません。新しい経路の確認に1往復以上かかり、送る速さの調整もやり直します。移れるのはクライアント側だけで、サーバは移行を受け付けないと宣言することもできます。

HTTP/3を有効にしてよいか:HTTP/2を残したまま足す

HTTP/3は、TCPの置き換えではなく、追加の経路として足します。Chrome・Edgeは87以降、Firefoxは88以降、Safariは16以降で、HTTP/3が既定で有効です。ただし、RFC 9308が紹介する測定では、3〜5%のネットワークがUDPをすべて止めていました。

規格は、QUICで接続できないときはTCPを使うHTTPを試すよう、クライアントに求めています。そのためTCPの受け口を残しておけば、UDPが止まっている利用者もこれまでどおり表示できます。TCPとUDPの両方の443番を受けるのが、ふつうの形です。

ブラウザがHTTP/3を知る流れ

URLを見ただけでは、サーバがHTTP/3に対応しているか分かりません。そこでサーバは、TCPのレスポンスのヘッダで知らせます。

  1. 1

    サーバが知らせる

    TCPで返すレスポンスに、Alt-Svcヘッダを付けます。

  2. 2

    ブラウザが覚える

    書かれた秒数の間、HTTP/3の接続先を覚えておきます。

  3. 3

    QUICで接続を試す

    UDPで接続できれば、HTTP/3でリクエストを送れます。

  4. 4

    失敗したらTCPを使う

    UDPが通らなければ、HTTP/2やHTTP/1.1で通信を続けます。

Alt-SvcHTTP/3の接続先を知らせるヘッダの例
Alt-Svc: h3=":443"; ma=86400

# h3=":443"
#  同じホストのUDP 443番で受け付ける
# ma=86400
#  86400秒(24時間)覚えてよい

DNSでも知らせられます。DNSのHTTPSレコードにalpn=h3と書く方法です。これならブラウザは、最初のTCP接続を待たずにHTTP/3に対応していると分かります。

有効にする前に確かめること

設定のスイッチを入れる前に、UDPの通信が通る経路かどうかを確かめます。ファイアウォールで開けているのがTCP 443だけなら、UDP 443は届きません。

確かめる場所確かめること見落とすと
サーバの前のファイアウォールUDP 443の受信を許可しているかQUICが届かず、ずっとTCPのまま動く
ロードバランサQUICを扱えるか。振り分けにコネクションIDを使えるか回線が切り替わった通信が別のサーバに届く
TCP 443HTTP/2やHTTP/1.1の受け口を残しているかUDPを通さないネットワークから接続できなくなる
UDPの流量制限パケット単位で間引いていないかTCPに戻らないまま、損失の多い接続が残る
0-RTTの設定同じリクエストが2回届いても困らないか注文などの処理が2回動くおそれがある

UDPは送信元を偽りやすいので、QUICには増幅攻撃の対策があります。サーバは送信元を確認するまで、受け取った量の3倍までしか返しません。そのためクライアントは、最初のパケットを1200バイト以上にふくらませて送ります。

有効にすれば必ず速くなるわけではない

効果が大きいのは、パケットが失われやすい回線や、新しい接続を作る回数が多いサイトです。損失がほとんどなく接続を使い回せる環境では、差は出にくくなります。CDNでスイッチを入れた場合、QUICで接続する相手はエッジサーバです。オリジンサーバまでの区間は別の接続です。

とても速い回線では、HTTP/3のほうが遅いとする測定もあります。2024年の論文は、受信側の処理が重いため、速度がHTTP/2より最大で45.2%低くなったと報告しています。切り替えるときは、自分のサイトの表示時間を測って比べるのが確実です。

HTTP/3が使われているか確かめる方法

手軽なのは、Chromeの開発者ツールです。リクエストごとに、使った版が分かります。

  1. 1

    Networkパネルを開く

    開発者ツールを開き、Networkのタブを選びます。

  2. 2

    Protocolの列を出す

    表の見出しを右クリックして、Protocolにチェックを付けます。

  3. 3

    ページを読み込み直す

    h3ならHTTP/3、h2ならHTTP/2です。

開いているページの本体だけを調べるなら、開発者ツールのConsoleで次の1行を実行します。

Consoleページ本体のプロトコルを表示する
performance.getEntriesByType('navigation')[0].nextHopProtocol
'h3'

サーバがHTTP/3を知らせているかは、curlでレスポンスのヘッダを見れば分かります。次の例は、2026年10月に実行した結果です。

curlAlt-Svcヘッダを確かめる
$ curl -sI https://example.com | grep -i alt-svc
alt-svc: h3=":443"; ma=86400

Alt-Svcが出ていても、毎回h3になるとは限りません。QUICを試すかどうかは、クライアントが決めるからです。実際にChromeでexample.comを何度か開くと、h2になるときとh3になるときがありました。

何度開いてもh2のままなら、別の回線でも試します。スマホのモバイル回線でh3になるなら、社内や自宅の経路でUDP 443が止まっている可能性があります。

練習問題(全6問)

Q1HTTP/3の説明として正しいものは?
Q2HTTP/2で、画像のデータを運ぶTCPのパケットが1つ失われた。このとき起きることは?
Q3往復に40ミリ秒かかる回線で初めて接続する。TCPとTLS 1.3の場合に比べて、QUICならリクエストを送れるまでの時間はどれだけ短い?
Q40-RTTを使うときに気を付けることは?
Q5QUICがWi-Fiからモバイル回線への切り替えで接続を続けられる理由は?
Q6ネットワークのファイアウォールがUDP 443を止めている。HTTP/3に対応したサイトをブラウザで開くと、ふつうはどうなる?

選んでから「採点する」を押すと、解説つきで答え合わせができます。

参考にした資料

関連記事

おすすめの本 PR

ネットワークを初めて学ぶ人向けの入門書です。

目的別の本の選び方を見る

ネットワークの記事を探す