Packet Path/

BDP Explained: Why a Fast Link Still Feels Slow

The bandwidth-delay product — BDP for short — is how much data has to be in flight, sent but not yet acknowledged, to keep a link completely full. It is simply the link's bandwidth multiplied by the round-trip time, and it explains a puzzle every network engineer meets sooner or later: a fast link that delivers slow transfers. When the TCP window is smaller than the BDP, the sender runs out of permission to send and the link idles between bursts, no matter how fast the link itself is.

Data Center · Intermediate · 11 min · October 30, 2026

Editorial illustration on a dark teal background: two data center buildings joined by a long glowing conveyor-like link, with dozens of small glowing data packets in flight along its whole length; a gauge motif on the left building and a clock motif on the right.

The short answer

\n

What is the bandwidth-delay product? It is bandwidth multiplied by round-trip time: the amount of data that must be in flight — sent, but not yet acknowledged — at any moment to keep a path completely full. Every path has this number whether you compute it or not, and it quietly decides how fast any single transfer on that path can go.

\n

Take a modern long-haul path: 100 Gbps of bandwidth and an 80 ms round-trip time. Its BDP is 1 GB — a gigabyte of data must be on the wire at every instant for that link to run at full speed. Now send one ordinary TCP connection down it with a classic 64 KB window, and the transfer runs at about 6.6 Mbps. The link is fine. The sender is simply not allowed to have enough data in flight to fill it, so most of the pipe sits empty most of the time. This article is about that gap — and the three things that close it: a window at least as big as the BDP, window scaling to make such a window legal, and loss low enough that the second ceiling does not take over.

\n

Think of the path as a motorway between two cities. Bandwidth is the speed limit combined with the number of lanes: how many cars per hour the road could carry if it were full. Round-trip time is how long the road is, measured as the time a car takes to make the trip and report back. The bandwidth-delay product is the number of cars that must be on the road at the same moment for the road to actually carry traffic at its rated capacity.

\n

A short, fast road needs only a few cars on it to look busy. A very long, very fast road needs an enormous number — leave it with only a handful of cars and it looks deserted, however high the speed limit is. A small TCP window is exactly that rule: only a handful of cars allowed on the road at once. Your cars still travel at full speed; there are just never enough of them. The road's capacity is wasted, and your effective speed — cars arriving per hour — collapses.

\n
In plain EnglishBandwidth: how much data a link can carry per second, in bits — its speed and width combined. Round-trip time (RTT): how long a packet takes to reach the far end and its acknowledgement to come back, measured in milliseconds — the length of the road, expressed in time. In flight / unacknowledged: data that has been sent but that the receiver has not yet confirmed receiving. TCP window (receive window): how much unacknowledged data the receiver allows the sender to have outstanding at once; the sender may not pass it. Window scaling: a TCP option that multiplies the window by a power of two, so it can grow far beyond 64 KB. MSS (maximum segment size): the largest chunk of data carried in one TCP packet, typically 1,460 bytes on ordinary Ethernet.
\n

The formula, worked three ways

\n

The formula is a single multiplication: BDP = bandwidth × RTT. The only skill involved is keeping the units honest — bandwidth in bits per second, RTT in seconds, and the answer comes out in bits; divide by 8 for bytes. Here are three paths worked exactly. The first row is the free calculator's own defaults, linked at the end of this article.

\n \n \n \n \n \n
PathBandwidthRTTBDP in bitsBDP in bytes
Calculator defaults1 Gbps50 ms50,000,0006.25 MB
Data center10 Gbps1 ms10,000,0001.25 MB
Long-haul headline100 Gbps80 ms8,000,000,0001,000 MB (about 954 MiB)
\n

The headline row, line by line. Bandwidth: 100 Gbps = 100 × 109 bits per second. RTT: 80 ms = 0.080 seconds. Multiply: 100 × 109 × 0.080 = 8 × 109 bits. Convert: 8 × 109 ÷ 8 = 1 × 109 bytes — 1,000 MB, or about 954 MiB (a MiB is 1,048,576 bytes, slightly more than a MB). Counted in ordinary 1,500-byte packets, that is 1,000,000,000 ÷ 1,500 ≈ 666,667 packets in flight at once. That is what \"full\" means on this path: not a burst, but a permanent condition.

\n

Why the window is the ceiling

\n

TCP's reliability rule creates the ceiling. A sender may have at most one window of unacknowledged data outstanding; when the window is used up, it must stop and wait. Acknowledgements take one round-trip time to come back, so the fastest a single connection can ever go is throughput ≤ window ÷ RTT — one window per round trip, forever.

\n

The classic window is tiny. In the original TCP design (RFC 793) the window is a 16-bit field in the header, so the largest window a receiver can advertise is 65,535 bytes — call it 64 KB. Now the arithmetic: 65,535 bytes × 8 = 524,280 bits per round trip. On the 80 ms path, 524,280 ÷ 0.080 ≈ 6.6 Mbps. On a 50 ms path, 524,280 ÷ 0.050 ≈ 10.5 Mbps. The link speed does not appear in either sum — a 1 Gbps link and a 100 Gbps link return the same answer.

\n

That is the whole explanation of \"we have a 1 Gbps circuit, but the backup runs at 10 Mbps.\" The sender fires one small window across, then sits idle waiting for permission to send more. The link is busy for a few percent of each round trip and empty for the rest.

\n

Window scaling: removing the 64 KB ceiling

\n

The fix is window scaling (RFC 7323). During connection setup, each side can include a window scale option in its SYN packet carrying a shift count from 0 to 14. From then on, every window value that side advertises is multiplied by 2 raised to the shift — so the maximum possible window becomes 65,535 × 214 = 1,073,725,440 bytes, about 1 GB. The option can only be negotiated in the SYN; a connection that starts without it is stuck at 64 KB for its whole life.

\n

How big a shift does the headline path need? It needs a window of at least 1,000,000,000 bytes, and 1,000,000,000 ÷ 65,535 ≈ 15,259 — so the multiplier must be at least 15,259. A shift of 13 gives 213 = 8,192: not enough. A shift of 14 gives 214 = 16,384: enough. This path needs the maximum shift, with nothing to spare.

\n

Two warnings. Both sides must offer the option — one silent side disables it for the whole connection. And a middlebox that strips TCP options (some firewalls, NATs and proxies do) removes scaling silently, leaving a connection that looks perfectly healthy and still runs at window ÷ RTT. In practice, modern operating systems negotiate scaling and auto-tune their buffers by default, so the real-world fix is usually to check that scaling is on and that no application has pinned a small fixed buffer — not to hand-set one magic number.

\n

Here is the same 80 ms path drawn twice — once with a window that covers the BDP, and once with the classic 64 KB window:

\n \n The 80 ms path at 100 Gbps: what \"in flight\" really means\n Window scaled — 1 GB in flight, the link runs full\n \n \n \n \n \n \n \n \n \n \n \n Classic 64 KB window — a few packets, then empty road: about 6.6 Mbps\n \n \n \n \n EMPTY — SENDER WAITS FOR ACKNOWLEDGEMENTS\n Same link, same speed limit — the window alone decides which picture you get.\n \n

And the three worked examples side by side — notice how the data-center path needs almost nothing, while the long-haul path needs nearly a gigabyte:

\n \n BDP for the three worked examples\n 10 Gbps × 1 ms — data center\n \n 1.25 MB\n 1 Gbps × 50 ms — calculator defaults\n \n 6.25 MB\n 100 Gbps × 80 ms — long-haul headline\n \n 1,000 MB\n Bar lengths use a log scale — on a linear scale the first two bars would be too thin to see.\n \n

Loss: the second ceiling

\n

Suppose the window is fixed. A single TCP flow can still be capped — by packet loss. Classic TCP treats a lost packet as the signal to slow down, and in steady state that behaviour has a well-known bound, the Mathis bound. In the simplified form the calculator uses: throughput ≈ MSS in bits ÷ (RTT × √p), where p is the loss rate written as a fraction and √ means square root.

\n

Work it with an MSS of 1,460 bytes — 11,680 bits — on the 80 ms path. At 0.1% loss (p = 0.001, √p ≈ 0.0316): 11,680 ÷ (0.080 × 0.0316) ≈ 4.6 Mbps. At 0.01% loss (√p = 0.01): about 14.6 Mbps. At 0.001% loss (√p ≈ 0.00316): about 46 Mbps. Loss rates that look like rounding errors take a fast path down to single-digit megabits.

\n

Read this as what it is: an approximate steady-state bound for classic loss-based congestion control — the Reno and CUBIC family, which slows down when it sees loss. Newer BBR-style control models the path's bandwidth and delay directly and does not obey the same bound. And the bound applies per flow: eight parallel streams get eight bounds between them, which is why a multi-stream speed test looks so much faster than the single file copy a user is complaining about.

\n

When BDP matters — and when it does not

\n

Inside a data center, RTT is around 1 ms, and at 10 Gbps the BDP is only 1.25 MB. Scaled windows cover that easily and defaults usually cope, so BDP is rarely the problem there. It bites where distance or speed grows: long-haul WAN links, replication between regions, backups sent to another site, satellite paths — anywhere the product of bandwidth and delay gets large. The rule of thumb: the faster and the further, the bigger the BDP, and the more the window decides your throughput.

\n

One honest footnote about other transports. QUIC runs over UDP, but it has its own built-in flow control, and the same in-flight logic applies — its windows must cover the BDP too. Raw UDP has no window at all: nothing stops the sender, and the application itself decides how much to have outstanding, for better or for worse.

\n

Four BDP mistakes that actually happen

\n

1. Upgrading bandwidth to fix a window problem. A faster link raises the BDP and leaves throughput at window ÷ RTT — exactly where it was. You have bought a wider empty road.

\n

2. Testing with a single stream and blaming the link. One flow is bounded by the window and by the loss bound all on its own. A link that \"fails\" a single-stream test may carry an application's many streams perfectly well — test the way the traffic actually flows.

\n

3. Pinning small fixed socket buffers. A fixed buffer size set years ago overrides the operating system's auto-tuning and hard-caps the effective window on every connection, forever. It is one of the most common reasons a healthy-looking server is slow across distance.

\n

4. Ignoring loss because the interface shows no errors. Interface counters can read zero while queues somewhere upstream drop one packet in a thousand. At 80 ms of RTT that invisible 0.1% bounds a single flow near 4.6 Mbps — the loss does not have to be visible to be decisive.

\n
Fact-check sourcesClassic window limit: RFC 793 — the TCP header's window field is 16 bits, so the largest unscaled window is 65,535 bytes. Window scaling: RFC 7323 — the window scale option is exchanged only in SYN segments, the shift count runs from 0 to 14, and the maximum effective window is 65,535 × 214 = 1,073,725,440 bytes, about 1 GB. Loss bound: the Mathis bound in the simplified form implemented by this site's own BDP calculator — throughput ≈ MSS in bits ÷ (RTT × √loss fraction). Every other number in this article is arithmetic from the inputs stated next to it.
\n

Try it yourself

\n

Run the headline example in the free Bandwidth-Delay Product Calculator: set 100 Gbps and 80 ms and it asks for 1,000 MB in flight and window scaling at shift 14; then try its defaults — 1 Gbps, 50 ms, MSS 1,460 bytes — and watch the BDP shrink to 6.25 MB while the loss slider prices what packet loss does to a single flow. To prove the single-stream point on a real path, build the test with the iPerf3 command builder: run one stream, then several in parallel, and compare. And the MSS that feeds the loss bound comes from the MTU/MSS calculator — 1,460 bytes is the answer for ordinary Ethernet; tunnels make it smaller.

\n

Related guides

Key takeaways

Keep reading