NetCalcLab

TCP BDP / Throughput Calculator

Work out the bandwidth-delay product, the throughput a given TCP window allows, the window size needed to fill a link, and how much throughput a packet loss rate permits. Every result states the model's assumptions explicitly rather than presenting a theoretical bound as a prediction.

Part 1 — Bandwidth delay product

How much data must be in flight to keep the link busy end to end. This is bandwidth × RTT.

Part 2 — Window limited throughput

A fixed TCP window can only put one window of data on the wire per RTT, which caps throughput regardless of how fast the link is.

Part 3 — Required TCP window

Work backwards: what window do you need to reach a target throughput at a given RTT, and does it require the window scale option?

Part 4 — Loss-limited throughput (Mathis model)

Packet loss caps TCP throughput far more aggressively than most people expect, because congestion control treats every loss as a signal to halve the rate.

0.001 means one lost packet in a thousand.

Why long fat networks underperform

A link with high bandwidth and high latency is called a long fat network. TCP was designed when both were small, and the 16-bit window field in the original header is the reason. If the sender can only have one window of data on the wire per round trip, throughput is capped by the window divided by the RTT — and the link's actual capacity never enters the calculation.

The two fundamental equations
Bandwidth-delay product (BDP):
  BDP (bits) = bandwidth (bps) × RTT (seconds)

Window-limited throughput:
  Throughput (bps) = window size (bits) ÷ RTT (seconds)
                   = window bytes × 8 ÷ RTT seconds

Required window for a target:
  Window (bytes) = target bps × RTT seconds ÷ 8

Working through a real example

Take a 10 Gbps link between two sites 25 ms apart, so the RTT is 50 ms.

Example: filling a 10 Gbps link across a 50 ms RTT

Step 1 — the BDP, which is the target:

10,000,000,000 bps × 0.05 s = 500,000,000 bits = 62,500,000 bytes = 62.5 MB

Step 2 — what a default 64 KB window achieves:

65,536 bytes × 8 ÷ 0.05 s = 10,485,760 bps ≈ 10.5 Mbps

That is 0.1% of the link. The link is not the problem — the window is.

Step 3 — the window needed, and the scale factor to advertise it:

Required window = 62,500,000 bytes 62,500,000 ÷ 65,535 = 954, so a scale factor of 2^10 = 1024 works

With window scaling enabled and both endpoints' buffers sized above 62.5 MB, a single flow can approach the link rate. Without it, no amount of bandwidth helps.

The role of packet loss

Congestion control treats packet loss as evidence of congestion and reduces the sending rate. On a path with loss, throughput is limited by the loss rate rather than by the window or the bandwidth.

Mathis et al. approximation
Throughput ≈ (MSS ÷ RTT) × (C ÷ √p)

MSS = maximum segment size in bits
RTT = round-trip time in seconds
p   = packet loss probability
C   ≈ 1.22 for an AIMD (Reno-style) sender

Example: MSS 1460 bytes, RTT 50 ms, loss 0.1% (p = 0.001)
  Throughput ≈ (11,680 ÷ 0.05) × (1.22 ÷ √0.001)
             ≈ 233,600 × 38.6
             ≈ 9,017,000 bps ≈ 9 Mbps

Nine Mbps on a link that might have 10 Gbps of capacity. This is why network engineers obsess over loss on long paths, and why a 0.1% loss rate that looks negligible on a monitoring graph is catastrophic for bulk transfer.

Two important caveats. The Mathis model describes a Reno-style AIMD sender in steady state; CUBIC, the default on modern Linux and macOS, is significantly less loss-sensitive. And real loss is often bursty rather than the uniform random process the model assumes, which changes the result further. Treat the output as an order-of-magnitude guide.

Tuning checklist for a long fat network

  • Enable window scaling on both endpoints. It is on by default in modern kernels, but a middlebox or an old appliance can strip the option during the handshake.
  • Raise socket buffer maximums. On Linux, net.core.rmem_max and net.core.wmem_max bound how far autotuning can go. Autotuning only helps if the ceiling is high enough.
  • Check the actual in-flight window with measurements. Packet capture or ss -ti shows the real cwnd and rwnd rather than the theoretical values.
  • Use parallel streams when you cannot tune the endpoints. Each flow gets its own window, so ten streams can achieve roughly ten times the single-flow rate on a high-latency path.
  • Eliminate loss before anything else. Every other tuning step is wasted effort if the path is dropping packets.

Reference values

Bandwidth-delay product for common link and latency combinations
RTT100 Mbps1 Gbps10 Gbps100 Gbps
1 ms (same rack)12.5 KB125 KB1.25 MB12.5 MB
10 ms (metro)125 KB1.25 MB12.5 MB125 MB
50 ms (cross-country)625 KB6.25 MB62.5 MB625 MB
100 ms (transatlantic)1.25 MB12.5 MB125 MB1.25 GB
200 ms (intercontinental)2.5 MB25 MB250 MB2.5 GB

Read this as the amount of data that must be in flight to saturate the link. Any figure above 65,535 bytes in the 1 Gbps column requires TCP window scaling, which in practice means every row except the very shortest latencies.

Related reading: the TCP throughput guide covers congestion control behaviour in more depth, and the MTU / MSS calculator shows how tunnel overhead changes MSS and therefore segment counts.

Frequently asked questions

What is the bandwidth-delay product?

The bandwidth-delay product (BDP) is the amount of data that must be in flight to keep a link fully utilised. It equals bandwidth multiplied by round-trip time. On a 10 Gbps link with a 50 ms RTT, the BDP is 10,000,000,000 × 0.05 = 500,000,000 bits, or 62.5 MB. That means 62.5 MB of unacknowledged data must be outstanding at all times to fill the pipe.

Why is my throughput poor on a fast link with high latency?

Almost always because the TCP window is too small to cover the BDP. A sender with a 64 KB window over a 100 ms RTT can only achieve 64,000 × 8 ÷ 0.1 = 5.12 Mbps, no matter how fast the underlying link is. Fixing it needs TCP window scaling enabled at both ends and adequate socket buffer sizes, not a faster link.

How do I calculate the TCP window size I need?

Window in bytes = target throughput in bits per second × RTT in seconds ÷ 8. For 10 Gbps over a 100 ms RTT that is 10,000,000,000 × 0.1 ÷ 8 = 125,000,000 bytes, or 125 MB. Because the TCP header's window field is only 16 bits, anything above 65,535 bytes requires the window scale option from RFC 7323.

What is TCP window scaling?

The original TCP header has a 16-bit window field, capping the advertised window at 65,535 bytes. The window scale option, negotiated during the handshake, multiplies that field by a power of two, allowing windows up to 65,535 × 2^14 = 1,073,725,440 bytes. Without it on both endpoints, no amount of buffer tuning will help on a long, fast path.

How does packet loss affect TCP throughput?

Severely. Roughly, throughput scales with 1 divided by the square root of the loss rate, so a loss rate going from 0.01% to 1% cuts throughput by about a factor of ten. This is why even 0.1% loss on a long-distance link destroys performance that looks fine on paper. The Mathis model in the calculator estimates this, but it is an approximation rather than a prediction.

Does this calculator predict my actual throughput?

No, and no online calculator can. These are theoretical upper bounds for a single flow on a lossless path with no competing traffic. Real throughput also depends on congestion control algorithm, receive window autotuning, CPU load, application behaviour and the characteristics of every device along the path. Use these figures to understand which constraint applies, then measure to find the real number.

What is the difference between the receive window and the congestion window?

The receive window (rwnd) is advertised by the receiver and reflects how much buffer space it has. The congestion window (cwnd) is maintained by the sender and reflects what the network appears able to handle. The actual amount of data in flight is the minimum of the two. The BDP tells you the ceiling, rwnd limits what the receiver will accept, and cwnd limits what the sender will risk.