HTTPバージョンの話が出ると、たいていこんなことを考えます。
「結局、ウェブは全部HTTPじゃないの?1.1と2って何がそんなに違うの?」
「新しいバージョンのHTTP/2だけを使えばいいじゃない?」
まとめると:
- HTTP/1.1とHTTP/2は「完全に異なるプロトコル」というより、HTTPのセマンティクス(メソッド、ヘッダー、ステータスコードなど)をより効率的に伝達する方法の違いです。
- 実際のサービスでは「どちらか一方を選択する」のではなく、サーバーが両方をサポートし、クライアントが選択できるようにしているのが一般的です。
以下では、開発者の観点からポイントをまとめてみます。
1. HTTP/1.1の簡単なまとめ
1) テキストベースのプロトコル
HTTP/1.1は我々がよく見るリクエスト/レスポンス形式です。
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234
<html>...</html>
- 人間が読めるテキストベースなのでデバッグが簡単で、
curlやtelnet、ncなどのツールで手軽に確認できます。
2) Persistent Connection + Pipelining
HTTP/1.0の大きな問題は、リクエストごとに新しいTCP接続を開くことでしたが、
HTTP/1.1では基本的にpersistent connection (keep-alive)が導入され、
1つの接続上で複数のリクエストを順番に送信できるようになりました。
さらにHTTP pipeliningという機能もありましたが:
- 応答を待たずにリクエストを連続して送信し、
- 順番に応答を受け取る方式です。
しかし、実際のブラウザではほとんど使用されておらず、
依然として「順番に処理しなければならない構造」なので、性能上の問題が残ります。
3) HOL(Head-of-Line) Blocking問題
HTTP/1.1の象徴的なボトルネックがHOL(Head-of-Line) Blockingです。
- 1つの接続でリクエストを順番に処理しなければならないため、
- 最初のリクエストが遅延すると後続のリクエストも待機させられることになります。
- そのため、ブラウザは1つのドメイン(origin)ごとに複数のTCP接続を開く(例えば最大6個)ことでこの問題を緩和してきました。
要約すると:
HTTP/1.1は「複数のパイプを作ることでボトルネックを減らす方式」です。
(複数のTCP接続)
2. HTTP/2は何が違うのか?
HTTP/2の目標は明確です。
- 遅延(latency)を減らすこと
- ネットワークリソースをより効率的に使うこと
核心的なキーワードを挙げると:
- バイナリフレーミング(Binary Framing)
- ストリーム(Stream)ベースのマルチプレクシング(Multiplexing)
- ヘッダー圧縮(HPACK)
- (元々は)サーバープッシュ(Server Push) – ブラウザでは実質的に利用されなくなった
2-1. テキスト → バイナリフレーミング
HTTP/1.1は行単位のテキストパースですが、HTTP/2ではすべてをフレーム(frame)というバイナリの塊に分けて送信します。
- ヘッダーはHEADERSフレーム
- 本文はDATAフレーム
- これらのフレームは特定のストリームIDに属します。
開発者が直接フレームに触れることはほとんどありませんが、
これによってマルチプレクシング、ヘッダー圧縮、優先順位などの機能を実装できます。
2-2. マルチプレクシング(Multiplexing)
最も体感できる違いです。
- HTTP/1.1: 1つのTCP接続でリクエスト-レスポンスを順番に処理
- HTTP/2: 1つのTCP接続で複数のストリームを同時に流します。
つまり、
「複数のTCP接続を開く必要がなく、
1つの接続内でリクエストとレスポンスを組み合わせて同時に送信すること」
こうすることで:
- 1つのHTMLページが数十〜数百のリソースを取得しなければならない場合でも、
- 1つの接続のみを維持しながら同時に取得できるため、
- モバイル環境や高RTT環境では特に大きなメリットがあります。
ただし、依然としてTCPレベルではHOL Blockingが残るため、この部分はHTTP/3(QUIC)がさらに改善した領域です。
2-3. ヘッダー圧縮(HPACK)
HTTPリクエスト/レスポンスヘッダーにはかなりの重複があります。
Cookie、User-Agent、Accept-*など- 毎回のリクエストで数百KBも含まれることがあります。
HTTP/2はHPACKというヘッダー圧縮方式を使って、
これらのヘッダー間の重複を減らします。
- よく使うヘッダーはテーブルに登録し、短いインデックスで送信
- 以前のリクエストとは異なった部分のみを効率的にエンコード
これにより、特にリクエストが多いSPAやリソースの多いページで大きなメリットがあります。
2-4. サーバープッシュ(Server Push)は事実上利用されなくなった
HTTP/2の初期には「サーバーがクライアントからのリクエストを待たずにCSS/JSなどを事前にプッシュする機能」であるサーバープッシュ(Server Push)も大きな利点とされていましたが、実際には:
- 実装難易度が高く、
- キャッシュ/重複リソースの問題
- 実際の性能改善がわずかで、逆に悪化するケースも
などがあり、Chrome/Chromium系は2022年以降デフォルトで無効化され(Chrome for Developers)
Firefoxも2024年にサポートを削除するなど、ブラウザエコシステムでは事実上利用されなくなった機能です。
そのため、最近HTTP/2の話をする際、サーバープッシュは「歴史的な機能」としてだけ見ることができます。
3. HTTPS、ALPN、そして「h2 vs http/1.1の選択」
実際のサービスで「HTTP/1.1を使うべきか、HTTP/2を使うべきか?」は、
クライアントとサーバーがTLSハンドシェイクの過程で自動的に交渉します。
これを担うのがALPN(Application-Layer Protocol Negotiation)というTLS拡張です。
- クライアント: 「私は
h2とhttp/1.1の両方ができます」 - サーバー: 「では
h2でいきましょう」 (または「私はhttp/1.1しかできません」)
Apacheの例設定:
Protocols h2 http/1.1
こう設定しておくと:
- HTTP/2をサポートする最新のブラウザは自動的にHTTP/2(h2)を使用
- 古いクライアントは自動的にHTTP/1.1で通信
ほとんどの主要なブラウザはすでにHTTP/2をよくサポートしており、
かなりの数のウェブサイトがHTTP/2を有効にしています。
4. 「どのような場合に使い分けますか?」 – 開発視点の整理
質問の核心であるこの部分をケース別に見ていきます。
4-1. 一般的なウェブサービス(ブラウザ対象)
正しい戦略に近い:
「HTTPS + HTTP/2を基本にオンにし、
HTTP/1.1はフォールバックとして有効にしておけば良い。」
- ほとんどのウェブサーバー(Nginx、Apache、Envoyなど)とCDNは、
HTTP/2サポートオプションをオンにするだけで自動交渉します。 - アプリケーションレベルで「このリクエストは1.1、あれは2で送ろう」と直接分けることはほとんどありません。
つまり、新しいサービスを作る場合、‘HTTP/2をオンにしたHTTPS’を基本設定と考えれば良いのです。
4-2. 内部API / マイクロサービス通信
ここではもう少し選択肢があります。
- すでにREST + HTTP/1.1でうまく動いているなら、
わざわざHTTP/2に書き直す必要はありません。 -
ただし、
-
同一サービス間で短いリクエストが非常に頻繁に発生する場合や、
- gRPCなどのHTTP/2ベースのプロトコルを使用する場合は、
→ HTTP/2を使うのが自然です。
つまり、
- 「既存のレガシーREST API」→ 1.1を維持 + 必要に応じてプロキシ/ロードバランサーでHTTP/2ターミネーション
- 「新たにgRPC導入、高頻度マイクロサービス呼び出し」→ HTTP/2を積極的に活用
4-3. デバッグ、ロギング、レガシー環境
HTTP/1.1が今でも有用な状況もあります。
- テキストベースなのでtcpdumpやWiresharkで内容が見やすい
- 古いプロキシ/ファイアウォール/クライアントはHTTP/2をサポートしないかもしれません。
- 単純な社内ツール、テストサーバーなどでは、わざわざHTTP/2を使わなくても十分です。
実際には多くの環境で:
- 外部(ブラウザ) ↔ フロントプロキシ(CDN/Load Balancer) : HTTP/2
- プロキシ ↔ バックエンドサービス : HTTP/1.1
構造が混ざり合っているケースが多いです。
5. 「HTTP/2のみを使用するのは適切か?」への現実的な回答
理論的には:
「新しく作る公開ウェブサービスであれば、HTTP/2を基本に考えても問題ありません。」
が正しいです。
しかし実務的には:
- HTTP/1.1を完全になくすのは難しい
- 古いクライアントや特別な環境は、今でも1.1しか使えません。
-
デバッグ/ツール/内部システムなどでは、1.1の方が楽な場合もあります。 2. サーバー視点では「両方をサポートする」ことが一般的
-
ウェブサーバー設定で
h2 http/1.1のようにオンにして、 -
クライアントがサポートする最高のプロトコルを自動的に選択させることが多いです。 3. HTTP/3(QUIC)まで考慮する時代
-
最新のブラウザやサービスは、すでにHTTP/3もサポートしています。
- しかし、これも通常「HTTP/1.1 + HTTP/2 + HTTP/3」を同時に有効にしておき、
クライアントが交渉で選ぶ構造です。
したがって、現実的な結論は:
「HTTP/2のみに限定するより、
HTTP/2を基本にオンにし、HTTP/1.1は自然なフォールバックとしておくのがベストです。」
です。

6. まとめ
一度に整理すると:
-
HTTP/1.1
-
テキストベース
- persistent connection + (理論上の) pipelining
- HOL Blocking問題によりブラウザは複数のTCP接続を開いて使用
-
HTTP/2
-
バイナリフレーミング
- 1つのTCP接続で複数のストリームを同時に処理するマルチプレクシング
- HPACKヘッダー圧縮
- サーバープッシュは実質的に廃止された
-
使用戦略
-
外部ウェブ(ブラウザ対象):HTTPS + HTTP/2をオンにし、HTTP/1.1はフォールバック
- 内部API:既存のRESTは1.1を維持もOK、高頻度/ストリーミング/gRPCならHTTP/2を積極的に活用
- デバッグ/レガシー:今でもHTTP/1.1が便利で役に立つ
開発者が覚えておくべき一言:
「アプリコードでバージョン選択に悩むことなく、
サーバーでHTTP/2をオンにし、残りはプロトコル交渉(ALPN)に任せましょう。」
コメントはありません。