Additive increase is too slow for a fast, long path — so CUBIC climbs back to the old rate quickly and only creeps once it gets there.
Words you will meet
- W_max — the congestion window at the moment loss was last detected.
- K — the time at which CUBIC’s congestion window is due to reach W_max again.
- β — the fraction of W_max that CUBIC drops to, about 0.7.
- L — the loss rate: the fraction of segments lost.
Why this matters
Section 3.7.1 ended on the saw tooth: halve on loss, then add one segment per round trip. It is a fine rule, and on a modern path it is far too slow.
Ask the obvious question. If the congested link has not changed much since the loss, why creep back? The old rate worked a moment ago. That question is the whole of TCP (Transmission Control Protocol) Transmission Control Protocol The Internet transport protocol that delivers data reliably and in order, with flow control and congestion control. introduced in ch. 1 CUBIC — and the arithmetic in the second half of this page shows exactly how much the creeping costs.
TCP CUBIC
TCP CUBIC tcp cubic Simple A TCP that climbs quickly back to its old window, then approaches it cautiously. Precise A congestion-control variant [Ha 2008, RFC 8312] that changes only the congestion-avoidance phase. Let W_max be the window when loss was last detected and K the time at which the window should reach it again; cwnd grows as the cube of the distance between the current time and K. The result is a fast climb when far from W_max, caution near it, and a fast climb again beyond it. It is the Linux default and, as measured in 2014, ran on about half of the 5,000 most popular Web servers [Yang 2014]. introduced in ch. 3 — open in glossary [Ha 2008, RFC 8312] differs only slightly from Reno. The congestion window is still increased only on acknowledgement receipt, and slow start and fast recovery remain exactly the same. CUBIC changes only the congestion-avoidance phase.
The rule, in three parts
Let W_max be the congestion window when loss was last detected. Let K be the future point in time at which that window would reach W_max again, assuming no further losses. Several tunable parameters determine K — that is, how quickly the protocol aims to get back.
- CUBIC increases the congestion window as a function of the cube of the distance between the current time t and K. So when t is far from K the increases are much larger than when t is close to it.
- Therefore it ramps up quickly to near the pre-loss rate, and only then probes cautiously as it approaches W_max.
- When t is greater than K, the increases stay small while t is still close to K. That is right if the congestion which caused the loss has not changed much. They then grow rapidly larger as t exceeds K, which lets CUBIC find a new operating point quickly if conditions genuinely have changed.
At 80.0 (move the pointer over the plot to read it anywhere):
- TCP CUBIC:0.700
- TCP Reno:0.500
- W_max:1.0
The book’s Figure 3.54 is adapted from [Huston 2017] and shows the two curves qualitatively, with losses marked at t₀ to t₄. These curves are generated from the actual rules — Reno halves and climbs linearly, CUBIC starts at βW_max and grows as the cube of the distance from K — with K placed at three-quarters of the inter-loss period. The shapes and their relationship are faithful; the exact loss times are not the book’s.
Both drawn as a fraction of W_max, the window when loss was last detected. Drag β to change how far CUBIC backs off, and watch how much of each period it spends near the top.
In plain words
Reno’s climb is a straight line: the same increase whether it is far below the old rate or almost back to it.
CUBIC’s is a flattened S. Fast where it is safe, far below a rate that worked a moment ago. Slow where it is risky, just under the level that caused the last loss. Then fast again past that point, on the reasoning that if it got this far without loss, the network has changed and it should go looking for the new limit.
The result is that CUBIC spends most of each cycle near the pre-loss rate, where Reno spends only about half. That is where the extra throughput comes from, on the same path with the same losses.
How widely deployed, and when
Measurements taken around 2000 on popular web servers showed nearly all running some version of TCP Reno [Padhye 2001].
More recent measurements of the 5,000 most popular web servers show nearly 50 % running a version of TCP CUBIC [Yang 2014]. It is also the default version of TCP used in Linux.
Note the dates. The second measurement is from 2014, in a book published in 2021, read now. Give the year whenever you quote either figure.
| TCP Tahoethe original | TCP Renoclassic TCP | TCP CUBICthe Linux default | |
|---|---|---|---|
| On three duplicate ACKs | |||
| On a timeout | |||
| Growth between losses | |||
| Time spent near the pre-loss rate | |||
| On a fast, long path | |||
| Deployment |
Cells marked ⓘ have a reason behind them — click to read it.
Each one changes exactly one thing about how the window recovers. Click a cell for the reasoning.
Macroscopic throughput
Now the arithmetic that justifies all of it.
Given the saw-tooth behaviour of Reno, what is the average throughput of a long-lived connection? Ignore the slow-start phases after timeouts — they are typically very short, since the sender grows out of them exponentially fast.
When the congestion window is w bytes and the round-trip time is RTT, the transmission rate is roughly w/RTT. TCP probes by increasing w by 1 MSS each round trip until a loss event. Call W the value of w when that loss occurs.
Assuming W and RTT are roughly constant over the connection, the rate sweeps from W/(2·RTT) up to W/RTT, is cut in half, and sweeps up again. Because it increases linearly between the two extremes, its average is the midpoint:
What each symbol means
- W — the window at the moment loss occurs (segments)
- MSS — maximum segment size (bytes)
- RTT — round-trip time, assumed roughly constant (s)
Read aloud: The rate sweeps steadily from half the peak up to the peak and back. Its average is therefore three-quarters of the peak.
Average throughput7.50 Mbps
at the moment of loss the window is W = 125 segments peak rate = W·MSS/RTT = 10.0 Mbps the rate sweeps from half that to all of it and back, linearly average throughput = 0.75 · W / RTT = 7.50 Mbps average window = 0.75 × 125 = 94 segments and climbing from W/2 back to W takes 63 round trips = 9.38 s
Change any number above and the arithmetic re-runs, carrying the units through.
The defaults are problem P48 exactly: a 10 Mbps link, 1,500-byte segments and a 150 ms round trip. Then set W to 125,000 for P50’s 10 Gbps link and look at the last line.
Now put a fast link into it
The defaults above are problem P48: a 10 Mbps link, 1,500-byte segments, a 150 ms round trip. W works out at 125 segments, average throughput 7.5 Mbps, and recovering from a loss takes 62 round trips — about 9.4 seconds. Slow, but survivable.
Now set W to 125,000, which is the same sum on a 10 Gbps link. That is problem P50, and the last line of the working is the point.
| W at loss | Average throughput | Time to climb from W/2 back to W | |
|---|---|---|---|
Cells marked ⓘ have an explanation — click to read it. Sortable columns have a ↕ in the heading.
Same protocol, same round trip, two link rates. The last column is the objection that CUBIC exists to answer.
In plain words
Two and a half hours to recover from one lost segment.
Additive increase adds one segment per round trip whatever the window is. That is a sensible rule when the window is a hundred segments and a hopeless one when it is a hundred thousand. The rule does not scale, and no amount of tuning the constants fixes it — which is why the growth function had to change.
What the removed subsection asked
A gap between the book’s problems and its text
Problem P55 opens by referring to “our discussion of TCP futures in Section 3.7”. It then asks you to derive the loss probability of 2 · 10⁻¹⁰ that a throughput of 10 Gbps would need.
There is no such discussion in section 3.7 of this edition. No “TCP futures” subsection, and the string “10 Gbps” does not appear in the section at all. It is a leftover — the subsection existed in an earlier edition and the problem set kept the reference.
The problem is still perfectly solvable, and worth solving. What it needs is the relationship between loss rate and throughput, which the book does mention. From the idealised model one can derive an expression relating a connection’s loss rate to its available bandwidth [Mathis 1997], and the derivation is outlined in problem P47.
So here it is.
P47, worked
(a) Over one saw-tooth cycle the congestion window runs W/2, W/2 + 1, …, W — that is W/2 + 1 round trips, sending one window of segments each. The total is
If exactly one packet is lost per cycle, the loss rate is the reciprocal:
(b) For large W the second term is negligible, so and . Substituting into the average-throughput result:
The constant is , which the book rounds to 1.22.
What each symbol means
- L — loss rate — the fraction of segments lost (—)
- MSS — maximum segment size (bytes)
- RTT — round-trip time (s)
Read aloud: Rearranged: to go this fast, on a path this long, the network must lose no more than this fraction of your segments.
Loss rate required2.14e-10
rate ≈ 1.22 · MSS / (RTT · √L)
so √L = 1.22 · MSS / (RTT · rate)
= 1.22 × 12,000 bits / (100 ms × 10.0 Gbps)
= 1.464e-5
L = 2.143e-10 — about one loss in 4,665,711,129 segments
that is a demand no real path meets; it is why classic Reno cannot fill a fast, long linkChange any number above and the arithmetic re-runs, carrying the units through.
The defaults are problem P55 — 10 Gbps with 1,500-byte segments over a 100 ms path. Read the last two lines, then try 100 Gbps.
And now P55 answers itself
With MSS 1,500 bytes and a 100 ms round trip, reaching 10 Gbps requires a loss rate of about
— roughly one loss in five billion segments. (The unrounded figure is 2.14 × 10⁻¹⁰, or one in 4.7 billion; the book’s 2 × 10⁻¹⁰ and “one in 5,000,000,000” are the same number rounded.)
For 100 Gbps, square the improvement: .
No real path is that clean. This is the quantitative case against classic Reno on fast, long links, and it is why every protocol in the next section exists.
A caution about the model itself
Everything above rests on a highly idealised picture: constant W, constant RTT, exactly one loss per cycle, slow start ignored.
The book is careful to say so, and points at a more sophisticated model that has been found empirically to agree with measured data [Padhye 2000].
Use these formulas the way the book intends — to see why a fast long path defeats additive increase, and roughly by how much. Do not use them to predict what a particular connection will do.
Check yourself
Check yourself
0 of 6 answered1.Which phase of TCP does CUBIC change?
2.predictOn the Reno-versus-CUBIC plot, why is the CUBIC curve nearly flat as it approaches W_max?
Look at what the cube is being taken of.
3.Why is the average throughput 0.75 · W / RTT rather than 0.5 · W / RTT?
4.predictSet the loss calculator to 10 Gbps with 1,500-byte segments and a 100 ms round trip. What loss rate does Reno need?
5.predictP48's path: 10 Mbps, 1,500-byte segments, 150 ms round trip. How long does Reno take to climb from W/2 back to W after a loss?
6.How widely is CUBIC deployed?
What to remember
- CUBIC changes only congestion avoidance. Slow start and fast recovery are identical to Reno’s.
- It grows as the cube of the distance from K, the time it is due to regain W_max. So it spends most of each cycle near the pre-loss rate, where Reno spends about half. Same path, same losses, more throughput.
- On a 10 Gbps path, recovering from one loss takes Reno about two and a half hours. Sustaining that rate needs a loss rate of about 2 × 10⁻¹⁰, and real paths are nowhere near that clean.