Skip to content

Set pieces, each with one thing to notice

Scenarios

Each one is a configuration that demonstrates a single named phenomenon.

Slow start into a shallow buffer

slow-start-shallow-buffer

"Slow start" doubles the window every round trip. It is slow to begin and then explodes, and on a shallow buffer it overshoots the pipe badly before the first loss tells it to stop.

What to look forThe window doubles cleanly — 1, 2, 4, 8 — then overshoots the buffer and collapses. Note how much of the run is spent recovering from an overshoot that took a fraction of a second.
Open scenario
Bandwidth
10.0 Mbps
Base RTT
20.0 ms
Buffer
6.1 KiB · 0.25 × BDP
Queue discipline
droptail
Algorithm
reno
Duration
20 s

Reno against CUBIC on a long fat pipe

long-fat-pipe

Reno adds one segment per round trip, so the time it needs to fill a pipe grows with the RTT. On 100 Mbps at 100 ms the window has to reach about 860 segments, and one-per-RTT will not get there. CUBIC grows as a cubic function of time since the last loss, so its recovery does not depend on how far away the other end is. This is why Linux changed its default.

What to look forReno reaches roughly 40% of the link in a minute. CUBIC reaches 85%.
Open scenario
Bandwidth
100.0 Mbps
Base RTT
100 ms
Buffer
1.19 MiB · 1.00 × BDP
Queue discipline
droptail
Algorithm
reno
Duration
60 s

Bufferbloat: DropTail against CoDel

bufferbloat-droptail

A loss-based sender fills whatever buffer it is given — that is what "loss based" means. Give it eight BDPs of buffer and it will put eight BDPs of data in the queue, adding hundreds of milliseconds of latency without losing a single packet. This is why a video call degrades when someone in the house starts a download.

What to look forThroughput barely differs between the two. Mean RTT differs by a factor of six: 325 ms against 51 ms, on a path whose propagation delay is 50 ms.
Open scenario
Bandwidth
50.0 Mbps
Base RTT
50.0 ms
Buffer
2.38 MiB · 8.00 × BDP
Queue discipline
droptail
Algorithm
cubic
Duration
60 s

Two identical flows converge

aimd-convergence

Chiu and Jain proved in 1989 that additive increase with multiplicative decrease converges to an equal share from any starting point. The second flow here arrives 20 seconds late, so it starts from as unequal a position as there is.

What to look forJain's index starts near 0.5 and climbs past 0.95. On the phase diagram, watch the trajectory staircase toward the point where the fair-share line crosses the capacity line.
Open scenario
Bandwidth
50.0 Mbps
Base RTT
50.0 ms
Buffer
305.2 KiB · 1.00 × BDP
Queue discipline
red
Algorithm
reno · reno
Duration
120 s

RTT unfairness

rtt-unfairness

Window growth is per round trip, so a flow with a quarter of the RTT increases four times as often and takes a correspondingly larger share. The two flows here are identical in every other respect.

What to look forThe short-RTT flow takes roughly the RTT ratio times as much. The queue is RED, deliberately: over a tail-drop queue the deterministic phase effect reverses the bias entirely.
Open scenario
Bandwidth
50.0 Mbps
Base RTT
25.0 ms
Buffer
305.2 KiB · 2.00 × BDP
Queue discipline
red
Algorithm
reno · reno
Duration
120 s

BBR v1 against CUBIC

bbr-vs-cubic

BBR v1 does not treat loss as a congestion signal. It measures the bottleneck bandwidth and the propagation delay and paces at that rate. Sharing a deep buffer with a loss-based flow, the two are optimising for different things — and how the capacity ends up divided is an actively contested question in networking, not a settled one.

What to look forWatch the queue depth. CUBIC pushes it up to find the limit; BBR tries to sit at the knee. Which one wins depends on the buffer, and the answer here is specific to BBR v1.
Open scenario
Bandwidth
50.0 Mbps
Base RTT
50.0 ms
Buffer
1.19 MiB · 4.00 × BDP
Queue discipline
droptail
Algorithm
cubic · bbr
Duration
120 s

Vegas against Reno: why delay-based lost

vegas-versus-reno

Vegas watched queueing delay and backed off before anything was dropped — in 1995, more than twenty years before BBR. It works: on its own it fills the link and leaves the queue almost empty. But it shares a bottleneck with a loss-based flow that only backs off when it loses a packet, and the capacity Vegas politely declines is simply taken by the flow next to it.

What to look forReno takes well over its share, and the queue depth tells you why: Reno keeps pushing it up, Vegas reads that as congestion and gives way. Being well-behaved is not a winning strategy when the other flow is not.
Open scenario
Bandwidth
50.0 Mbps
Base RTT
50.0 ms
Buffer
305.2 KiB · 1.00 × BDP
Queue discipline
red
Algorithm
vegas · reno
Duration
120 s

What SACK bought

sack-versus-newreno

Without selective acknowledgement the receiver can only say "still waiting", so the sender fills one hole per round trip. After a burst loss on a long fat path that is hundreds of round trips. With SACK the sender knows exactly which segments are missing and fills them all at once.

What to look forSame algorithm, same link, same seed. The only difference is whether the receiver can report gaps.
Open scenario
Bandwidth
100.0 Mbps
Base RTT
100 ms
Buffer
1.19 MiB · 1.00 × BDP
Queue discipline
droptail
Algorithm
cubic
Duration
60 s