What the bandwidth-delay product measures
Think of the path between two hosts as a pipe. Bandwidth is how wide it is; round-trip time is how long it is. Multiply the two and you get its volume — the amount of data that fits inside the network at one instant. That volume is the bandwidth-delay product, and it is the amount a sender must be allowed to have outstanding, unacknowledged, if the pipe is to stay full.
TCP limits outstanding data to the smaller of the congestion window and the receiver's advertised window. If that limit is below the product, the sender fills the window, stops, and waits for the first acknowledgement to come back before it can send again. The link then sits idle for most of every round trip, and throughput settles at window ÷ RTT no matter how fast the circuit is. This is the single most common reason a fast long-distance link performs like a slow one, and it is why the symptom is unmistakable: the transfer rate barely changes when you upgrade the circuit.
The effect scales with distance. At 1 ms round trip — within a data centre — a gigabit link holds 125 KB, comfortably inside any default buffer. Across the Atlantic at 80 ms it holds 10 MB, which is far outside the defaults most systems ship with. Networks in the second category are called long fat networks, and RFC 7323 exists to make them work.
If you want to know how long a given transfer takes once the window is right, use the data transfer time calculator; for sizing an aggregate link from user counts rather than a single stream, use the network bandwidth requirement calculator.
The formula and the three quantities it links
BDP = bandwidth × round-trip time. Keep the units honest: bandwidth in bits per second, time in seconds, and the answer comes out in bits. Divide by 8 for bytes, which is the unit every socket option is expressed in. A 1 Gbps path at 100 ms holds 1,000,000,000 × 0.1 = 100,000,000 bits, which is 12,500,000 bytes.
Round-trip time is used rather than one-way delay for a specific reason. The sender is not waiting for the data to arrive; it is waiting for permission to send more, and that permission travels back in an acknowledgement. The window therefore has to cover the outbound flight, the receiver's turnaround and the return flight — a full circuit.
Throughput with a fixed window = window × 8 ÷ RTT. Rearranging the same relationship gives the practical diagnostic. A 65,535-byte window on a 100 ms path yields 65,535 × 8 ÷ 0.1 = 5,242,800 bit/s, about 5.24 Mbps, and that figure is the same whether the circuit is 10 Mbps or 10 Gbps. What a window can never do is exceed the line rate, so the achievable figure reported above is the smaller of the two.
Window scale factor = ⌈log₂(BDP ÷ 65,535)⌉. The TCP header's window field is 16 bits, capping the advertised window at 65,535 bytes. RFC 7323 adds a scale option, negotiated only in the SYN and SYN-ACK, that left-shifts the advertised value by an agreed number of bits. A shift of 8 multiplies by 256, taking the ceiling to about 16 MB. The maximum shift is 14, giving roughly 1 GB, and paths whose product exceeds that cannot be filled by one stream at all.
Two practical notes about buffers. Most operating systems now auto-tune the receive buffer up to an administrator-set maximum, so the number that matters is usually that maximum rather than the default. And the send buffer needs to be at least as large as the receive window, because it holds the unacknowledged data awaiting possible retransmission.
Worked example: 1 Gbps London to New York at 80 ms
A research group copies datasets over a 1 Gbps circuit with a measured round-trip time of 80 ms and finds the transfer sits at about 6.5 Mbps. Work out why.
- Convert the bandwidth. 1 Gbps = 1,000 Mbps = 1,000,000,000 bit/s.
- Convert the delay. 80 ms = 0.08 s.
- Multiply. 1,000,000,000 × 0.08 = 80,000,000 bits in flight.
- Convert to bytes. 80,000,000 ÷ 8 = 10,000,000 bytes, which is 10,000,000 ÷ 1,048,576 = 9.537 MiB.
- Compare with the current window. The host is using the unscaled maximum of 65,535 bytes, which covers 65,535 ÷ 10,000,000 = 0.66% of the product.
- Predict the throughput. 65,535 × 8 ÷ 0.08 = 6,553,500 bit/s = 6.55 Mbps, which matches the measurement. The circuit is not the problem.
- Find the scale factor. 10,000,000 ÷ 65,535 = 152.6, and log₂(152.6) = 7.25, so the ceiling is 8. A shift of 8 multiplies the advertised window by 28 = 256, giving a ceiling of 16,776,960 bytes — comfortably above the 10,000,000 needed.
- Set the buffer. Raise the receive and send buffer maxima to at least 10,000,000 bytes. With the window matched to the product, one stream can reach 10,000,000 × 8 ÷ 0.08 = 1,000,000,000 bit/s, the full 1,000 Mbps.
Notice that steps 6 and 8 use the same expression with different windows: throughput is directly proportional to window size at fixed RTT, right up to the point where the line rate takes over as the binding constraint. That is the whole mechanism in one sentence.
How to read the result
Compare the product with your current buffer first. If the buffer is at or above the product, the window is not your limit and you should look elsewhere — packet loss, a slower hop than you assumed, disk throughput at either end, or a sender that is not offering data fast enough. If it is below, the shortfall figure is exactly how many more bytes you need, and the utilisation figure tells you what fraction of the circuit you are currently buying.
A window matched exactly to the product fills the link only when nothing goes wrong. Practitioners commonly provision two to three times the product so that TCP can keep sending while it recovers from a loss and while the congestion window rebuilds. That is a rule of thumb rather than a derived quantity, and it costs memory per connection, which is why servers with many concurrent flows tune the auto-tuning maximum rather than the default.
Loss changes the picture completely. The product tells you the window you need; it does not promise you will get it. Classic loss-based congestion control cannot sustain a large window on a lossy path, because each loss halves the congestion window and it then rebuilds by roughly one segment per round trip — slowly, when round trips are long. On a path with measurable loss the practical ceiling comes from the loss rate and the RTT together rather than from the buffer, which is why long-haul tuning normally starts by eliminating loss and only then raises buffers.
Read the scale factor as a configuration check, not a target. Window scaling is negotiated once, in the SYN exchange, and only if both ends offer it. A middlebox that strips or rewrites the option leaves the connection permanently unscaled no matter what the hosts are configured to do, and the symptom is a transfer that plateaus at exactly window ÷ RTT with no loss to explain it. Packet capture on the handshake settles that question in seconds.
Bandwidth-delay product at 1 Gbps by round-trip time
| Round-trip time | Typical path | Product (bytes) | Product (MiB) | Scale factor |
|---|---|---|---|---|
| 0.5 ms | Same rack or switch | 62,500 | 0.06 | 0 |
| 1 ms | Within a data centre | 125,000 | 0.12 | 1 |
| 10 ms | Metropolitan area | 1,250,000 | 1.19 | 5 |
| 30 ms | Coast to coast, one country | 3,750,000 | 3.58 | 6 |
| 80 ms | Transatlantic | 10,000,000 | 9.54 | 8 |
| 150 ms | Transpacific | 18,750,000 | 17.88 | 9 |
| 300 ms | Multi-hop intercontinental | 37,500,000 | 35.76 | 10 |
| 600 ms | Geostationary satellite | 75,000,000 | 71.53 | 11 |
Scale factor is ⌈log₂(product ÷ 65,535)⌉. At 0.5 ms the product already fits an unscaled window, so no scaling is required.
Assumptions and limits worth knowing
- The product describes one flow. Ten parallel streams share the same pipe, so each needs roughly a tenth of the window to fill it between them. Parallel transfer tools exploit exactly this, at the cost of being less friendly to other traffic.
- Bandwidth means the narrowest hop. A 10 Gbps interface into a 200 Mbps circuit has a 200 Mbps product. Measuring the bottleneck, not the interface, is the whole difficulty in practice.
- Round-trip time is not constant. Queueing adds delay under load, so the product grows exactly when the path is busiest. Measure RTT at realistic load, not on an idle link.
- Buffers cost memory per connection. A 16 MB window on 1,000 concurrent connections is 16 GB of kernel memory. Auto-tuning exists so the maximum is only reached by flows that need it.
- Oversized buffers in the network are a different problem. Bufferbloat is excess queueing inside routers, which inflates RTT and therefore inflates the product itself. Sizing endpoint buffers does not fix it; active queue management does.
- Modern congestion control changes the arithmetic. BBR paces to an estimate of bandwidth and minimum RTT rather than filling a window to loss, so it is far less sensitive to a single loss event — but it still cannot exceed the advertised receive window, so the product remains a hard floor for the buffer.
Where this fits in performance work
The bandwidth-delay product is the first calculation in any long-haul throughput investigation and rarely the last. A sensible order of work is: measure the true bottleneck rate and the round-trip time; compute the product; confirm the receive window can reach it and that scaling is actually negotiated; then measure loss. RFC 6349 sets out a formal version of this procedure for TCP throughput testing, including the ratio of achieved throughput to the ideal as a reportable metric.
Above the transport layer, application behaviour often matters more than the window. A protocol that makes one request per round trip is limited by RTT no matter how large the buffers are — the classic case is a file copy over a chatty protocol, where a hundred small operations cost a hundred round trips. Pipelining, larger block sizes and parallel connections are the fixes there, and none of them is a buffer setting.
Storage and backup work meets the same constraint from the other side. If you are checking whether a nightly copy fits its window, the backup window calculator works from the size and the achievable rate, and this page is how you find out whether that rate is realistic on the path you have. For encapsulated or tunnelled paths, subtract the header overhead first — the MTU, MSS and packet overhead calculator shows how much of the line rate the headers consume before any of this arithmetic starts.
Finally, keep the product in mind when someone proposes a longer path for resilience or compliance. Routing traffic through a distant scrubbing centre or inspection point adds round-trip time, and every millisecond added multiplies straight into the buffer every endpoint needs. A path change is a throughput change.
