TCP 帯域・遅延積 BDP ウィンドウ最適化 戻る
ネットワーク・TCP

TCP 帯域・遅延積 BDP ウィンドウ最適化

10 Gbps 級の太い回線でも、RTT が長いと既定の TCP ウィンドウでは速度が出ません。本ツールは BDP・必要ウィンドウ・Mathis 上限・TCP 変種・OS チューニングを一画面で計算し、ボトルネックがウィンドウ不足かパケット損失かを瞬時に切り分けます。

パラメータ設定
リンク帯域
Mbps
回線の物理帯域。1 Gbps=1000、10 Gbps=10000
往復遅延 RTT
ms
ping の往復時間。国内 10〜30、日米 80〜130、衛星 500〜800
TCP 変種
輻輳制御アルゴリズム。Linux 既定は CUBIC
MSS(最大セグメントサイズ)
B
標準 1460、ジャンボフレーム 9000
TCP ウィンドウサイズ
KB
送信側ソケットバッファ。BDP より小さいと回線が遊ぶ
パケット損失率
%
広域回線で 0.01〜0.1 %、WiFi で 1〜5 %
OS チューニング
sysctl rmem/wmem や qdisc の最適化レベル
計算結果
BDP (KB)
BDP (MB)
ウィンドウ使用率 (%)
Mathis 上限 (Mbps)
実効スループット (Mbps)
輻輳ウィンドウ (packets)
TCP パイプ可視化 — 帯域・ウィンドウ・ACK 往復

パイプの太さがリンク帯域、長さが RTT を表します。送信ウィンドウ分のパケットが流れ、受信側からの ACK が戻ってくると次のウィンドウが送信されます。ウィンドウが BDP より小さいとパイプに隙間ができます。

スループット感度 — ウィンドウサイズに対する実効速度
TCP 変種比較 — CUBIC / Reno / BBR / Vegas
理論・主要公式

$$\text{BDP} = \text{Bandwidth} \times \text{RTT}$$

帯域遅延積。リンク上を同時に飛んでいられるビット数の上限。RTT は秒単位。

$$\text{Throughput}_{\text{Mathis}} \approx \frac{\text{MSS}}{\text{RTT}} \cdot \frac{1}{\sqrt{p}}$$

Mathis 公式によるスループット上限。p はパケット損失率(小数)。損失の平方根の逆数で効くため、わずかな損失でも上限が大きく低下する。

$$\text{Throughput} \le \min(\text{Bandwidth},\ \tfrac{W}{\text{RTT}},\ \tfrac{\text{MSS}}{\text{RTT}\sqrt{p}})$$

実効スループットは「物理帯域・ウィンドウ律速・損失律速」の最小値で決まる。W は TCP ウィンドウサイズ(バイト)。

TCP BDP 帯域・遅延積 ウィンドウサイズ最適化 — 高速広域通信

🙋
10 Gbps の専用線を引いたのに、東京〜サンノゼ間でファイル転送したら 100 Mbps しか出ないんです。回線が壊れてるんでしょうか…?
🎓
回線は壊れてないよ、典型的な「BDP 不足」だね。BDP=帯域遅延積っていうんだけど、TCP は ACK が返ってこないと次のパケットを送れないから、回線にどれだけ「飛ばし続けられるデータがあるか」がスループットの上限を決めるんだ。10 Gbps × 80 ms ≈ 100 MB が BDP。これに対して Linux 既定の送信バッファは 4 MB くらいしかないから、100 MB に対して 4 %、つまり理論上 400 Mbps が頭打ち。100 Mbps しか出てないなら他の要因もあるけど、まずはここを潰そう。
🙋
なるほど!じゃあ送信バッファを 100 MB に増やせば 10 Gbps 出るんですか?左の「ウィンドウサイズ」を 65535 KB まで上げてみたら、確かに「ウィンドウ使用率」が 64 % まで上がりました。
🎓
いい感じだね。でも 65535 KB=64 MB は実は TCP の生のウィンドウサイズ上限なんだ。それ以上はウィンドウスケーリングオプション (RFC 1323) が必要になる。Linux なら net.ipv4.tcp_window_scaling=1 が既定で入ってるから、sysctl で rmem_max / wmem_max を 134217728 (128 MB) に増やせば 100 MB の BDP も埋められる。本ツールの「OS チューニング=最適化済」を選ぶと、その効果を 1.3 倍として概算してるよ。
🙋
パケット損失率も気になります。0.01 % から 0.1 % に上げただけで、Mathis 上限がガクッと下がりました。たった 0.1 % でこんなに効くんですか?
🎓
Mathis 公式は損失率の平方根の逆数で効くから、p が 10 倍になると上限は約 1/√10≈1/3.16 になる。これが「長距離回線で速度が出ない」現象の最大の犯人なんだ。WiFi で 1〜5 % の損失があると、CUBIC でも数 Mbps しか出ない。だから Google が BBR を作った。BBR は損失じゃなくて帯域と RTT を直接測るから、損失耐性が桁違いに高い。本ツールで「BBR」を選ぶと係数 1.5 倍になるよ。
🙋
CUBIC・Reno・BBR・Vegas って、どう使い分けるんですか?グラフを見ると BBR が一番速そうですが…
🎓
基本は「広域・高帯域なら BBR、社内 LAN なら CUBIC、低遅延が命なら Vegas」だね。BBR は速いけど、CUBIC と共存させると CUBIC の帯域を食い潰す「アンフェアネス」問題があるから、ISP のバックボーンや CDN では BBRv2/v3 への移行が進んでる。Reno は教科書には残ってるけど実運用ではもう使わない。Vegas は遅延を見て減速するから、ゲームや音声みたいにジッタが命の用途で意味がある。スループット最優先なら BBR、安定性なら CUBIC、低遅延なら Vegas、って覚えとくといいよ。
🙋
最後に、輻輳ウィンドウ (cwnd) って表示されてますけど、これって何ですか?ウィンドウサイズと違うんですか?
🎓
いい質問!TCP には「受信ウィンドウ rwnd」(受信側が告知する空きバッファ)と「輻輳ウィンドウ cwnd」(送信側が推定する回線の余裕)の 2 つがあって、実際に飛ばせるのは min(rwnd, cwnd) なんだ。本ツールで表示してる「輻輳ウィンドウ (packets)」は、ウィンドウサイズを MSS で割った「同時に飛ばせるパケット数」。例えば 64 KB ÷ 1460 B = 44 パケット。これが BDP=100 MB に対する 44 パケットだと回線がスカスカ。逆に 100 MB ÷ 1460 B ≈ 71800 パケット飛ばせれば 10 Gbps を埋め切れる、ってわけ。

よくある質問

BDP (Bandwidth-Delay Product) は「リンク帯域 × 往復遅延 (RTT)」で求めるネットワーク上を同時に飛んでいられるデータ量の上限です。例えば 10 Gbps の回線で RTT が 80 ms なら BDP は 10000 Mbps × 0.08 s = 800 Mbit ≈ 100,000 KB ≈ 97.66 MB になります。TCP の送信ウィンドウがこの BDP より小さいと、ACK 待ちで回線が遊んでしまい、太い回線を契約しても実効スループットが頭打ちになります。広域・高帯域ネットワークでは BDP を意識したウィンドウ設計が最重要です。
Mathis 公式は MSS と RTT、パケット損失率 p からスループット上限を概算する古典的な式で、Throughput ≈ MSS · 8 / RTT / sqrt(p) で書けます。損失率の平方根の逆数で効くため、p が 0.01 % から 0.1 % に増えると上限はおよそ 1/3 になります。広域ネットワークで「BDP は十分なのに速度が出ない」現象は、たいてい微小な損失が原因です。本シミュレーターはこの Mathis 上限と BDP 制約・OS チューニング・TCP 変種を組み合わせて、実効スループットを推定します。
Reno は最古典の AIMD(増加 1/RTT、損失時に半減)で、損失耐性が低く高帯域広域では性能が出ません。CUBIC(Linux のデフォルト)は時間の 3 乗関数で輻輳ウィンドウを増やすため、Reno より広域回線に強いのが特徴です。BBR(Google 開発)は損失ではなく帯域と RTT を直接推定するため、わずかな損失でも速度が落ちにくく、CUBIC の 1.5 倍程度の実効スループットが出やすい一方、共存性に課題があります。Vegas は遅延の増加を輻輳の前兆と見る低遅延向けで、損失前に減速します。本ツールでは各変種の係数を比較できます。
代表的な sysctl パラメータは net.core.rmem_max / wmem_max(ソケットバッファの上限)、net.ipv4.tcp_rmem / tcp_wmem(自動チューニング範囲)、net.ipv4.tcp_window_scaling(必須で 1)、net.ipv4.tcp_congestion_control(cubic / bbr)です。10 Gbps × 80 ms のような BDP=100 MB のリンクでは、デフォルトの 4 MB バッファでは全く足りないため、16〜128 MB に拡大する必要があります。BBR を使う場合は net.core.default_qdisc=fq とセットで有効化します。本ツールの「OS チューニング」で効果のオーダーを確認してから実機を触ると失敗が減ります。

実世界での応用

長距離データセンター間バックアップ:東京〜シンガポール (RTT 70 ms)、東京〜ロンドン (RTT 240 ms) のような国際線で 1 TB クラスのデータをコピーする場面では、BDP が 100 MB〜2 GB に達します。既定のソケットバッファでは 1 Gbps の回線でも 50 Mbps 程度しか出ません。rmem_max/wmem_max を BDP の 2〜3 倍に設定し、CUBIC または BBR を選び、aspera / scp の代わりに UDT / FASP / Multipath TCP を使うと、実効スループットが 10〜20 倍に改善します。

クラウドへのアップロード/CDN オリジン同期:S3 / Cloud Storage / Azure Blob への大容量アップロードは、内部的に並列 TCP セッションを張ることで BDP 制約を回避しています。AWS の「マルチパートアップロード」が 8〜16 並列を推奨するのは、1 セッションあたりのウィンドウ上限を並列化で乗り越えるためです。CDN のオリジン同期でも同様で、HTTP/2 のストリーム多重化や QUIC の採用は BDP 不足の根本対策になります。

衛星・無線リンク(Starlink・LEO・5G):衛星リンクは RTT が 500〜800 ms と長く、Starlink (LEO) でも 30〜50 ms あります。地上の 4G/5G より RTT が桁違いに大きいため、CUBIC では帯域の半分も使い切れないことが多いです。Starlink が BBR を採用しているのはこの理由で、損失率が変動しても帯域を維持できます。船舶・航空機通信や災害対応ネットワークでは BBR + 大バッファが標準的な構成になりつつあります。

金融取引・低遅延 HPC:逆に取引所への発注やインターコネクトでは「スループットより RTT を 1 μs でも縮める」のが目的です。ここでは BBR / CUBIC のような帯域追求型ではなく、Vegas や DCTCP のような遅延追求型を使い、バッファをあえて小さく保ちます。Cisco / Mellanox の HFT 向け NIC では TCP オフロード + カーネルバイパス (DPDK / Solarflare OpenOnload) で μs オーダーの遅延を実現します。

よくある誤解と注意点

最大の落とし穴は「ウィンドウサイズを大きくすれば速くなる」と思い込むことです。確かに BDP より小さいウィンドウはボトルネックですが、BDP を超えてウィンドウを増やすと今度は「バッファブロート (Bufferbloat)」が発生します。ルータのキューに過剰なパケットが溜まり、RTT が数倍に膨らみ、結果として VoIP やゲーム、双方向通信の品質が大きく劣化します。CoDel / FQ-CoDel / FQ といった AQM (Active Queue Management) を併用しないと、本ツールの「最適化済」設定でも逆効果になることがあります。BBR が損失より RTT を見るのは、まさにこのバッファブロートを回避するためです。

次に多いのが「Mathis 上限を絶対視する」こと。Mathis 公式は Reno の数学モデルで、CUBIC や BBR には正確には当てはまりません。CUBIC は損失耐性が Reno の 2〜3 倍、BBR はそもそも損失をシグナルにしないため、Mathis 公式で計算した上限を大きく超えるスループットが出ます。本ツールでは TCP 変種ごとに係数を乗じて補正していますが、これも一次近似です。実機での測定 (iperf3 -P 8 / TCP_INFO) と必ず突き合わせてください。

最後に「片方向だけチューニングすれば良い」という誤解。TCP は送信側 (sndbuf) と受信側 (rcvbuf) の両方のバッファサイズが効きます。AWS EC2 のような片側だけ rmem_max を上げても、相手側 (オンプレ) の wmem_max が小さければそちらが上限になります。BDP の半分以下のウィンドウしか張れず、スループットが頭打ちになります。両端で sysctl を揃えるか、可能なら自動チューニング (tcp_rmem / tcp_wmem) の上限を BDP の 2 倍以上に設定しましょう。さらに、ジャンボフレーム (MSS=9000) は L2 区間が全部対応していないと PMTUD 失敗で逆に遅くなるので、社内 LAN 限定で使ってください。

使い方ガイド

  1. 帯域幅(Mbps)、RTT(ms)、MSS(Byte)をスライダーまたは入力欄で設定します。例:帯域100Mbps、RTT50ms、MSS1460Byteは光回線の標準構成です
  2. TCP変種(CUBIC/Reno/BBR/Vegas)とOS設定(Linux/Windows/macOS)を選択すると、輻輳ウィンドウの成長則が自動切り替わります
  3. シミュレーション実行後、BDP値、ウィンドウ使用率、Mathis上限、実効スループットを確認して、TCPウィンドウサイズチューニングの必要性を判定します

具体的な計算例

帯域1Gbps、RTT100ms、MSS1460Byte、パケット損失率0.1%でCUBICを動作させた場合:BDP≈12.5MB、ウィンドウ使用率が65%であれば実効スループット≈650Mbpsとなります。Mathis上限はMSS÷(RTT×√損失率)で計算され、同条件では約920Mbpsです。Linuxカーネルでnet.core.rmem_max=134217728に設定すればウィンドウ使用率を90%以上に改善できます

実務での注意点

  1. 国際回線(RTT150ms以上)でCUBICを使用する場合、ウィンドウサイズがBDPの80%未満ではボトルネック帯域を使い切れません。BBRに切り替えると改善されます
  2. パケット損失率が1%を超えると、Mathis上限は急落(例:100Mbps帯域でも上限が20Mbps以下)し、TCPフローの再送処理が支配的になるため、下位レイヤーの品質改善が優先課題です
  3. WindowsサーバーはデフォルトRcvBufサイズが小さいため、レジストリのTcpWindowSizeを手動設定(推奨値:帯域×RTT÷8)しないと、長距離通信で実スループットがMathis上限の50%に低下する事例が多数報告されています