Why does loss-based TCP congestion control such as Reno or CUBIC underuse a lossy wireless link yet cause bufferbloat on a deep-buffered link, and how does BBR differ?
answer
- what does a drop really mean?
- random loss read as congestion
- back off only when the buffer overflows
- bandwidth and minimum RTT model
- a draft, not an RFC
basics
~20 sLoss-based TCP treats every drop as congestion: random wireless losses make it cut its window needlessly, and on deep buffers it keeps growing until the queue overflows. BBR instead models bottleneck bandwidth and minimum RTT and paces to that model.
solid answer
~50 sReno (RFC 5681) and CUBIC (RFC 9438) are **loss-based**: they grow `cwnd` until a drop or ECN mark and then cut it, by half for Reno or to 0.7 for CUBIC. On a **lossy wireless link**, drops come from the radio rather than a full queue, but each one still triggers a cut, so throughput stays far below capacity; RFC 9438 itself says CUBIC suffers where loss is not a good congestion signal. On a **deep-buffered link** the opposite happens: no drop arrives until the buffer is full, so the sender repeatedly fills it and every flow sees a long standing queue, **bufferbloat**. **BBR** (`draft-ietf-ccwg-bbr`, an Experimental Internet-Draft specifying BBRv3) estimates the bottleneck bandwidth and minimum RTT, paces at that rate and keeps in-flight data near their product. It tolerates low loss, but BBRv3 does back off when loss exceeds a threshold.
go deeper
Recall that Reno and CUBIC slow down when packets are lost, and that BBR instead estimates the path's bandwidth and round-trip time.
Explain why a loss that is not caused by congestion still halves a loss-based sender's window, and what a standing queue does to latency.
Diagnose a slow transfer on a radio link or a laggy link under load as the wrong congestion signal, and explain BBRv3's model and its loss threshold.
Weigh switching a fleet's algorithm: BBR's Experimental status and coexistence with CUBIC flows against its gains on lossy and deep-buffered paths.
## What a loss-based algorithm assumes Reno-style congestion control (RFC 5681) and CUBIC (RFC 9438) share one assumption: **a lost packet means a queue overflowed**. They grow the congestion window until a loss (or an ECN Congestion Experienced mark, which RFC 3168 says must be treated essentially like a single drop) and then apply a **multiplicative decrease**: Reno halves, CUBIC reduces to 0.7 of the window. RFC 9438 states plainly that CUBIC, like Reno, is loss-based. The assumption holds on a wired path whose bottleneck queue is moderately sized. It breaks in two opposite directions. ## Case 1: a lossy wireless link On a radio link, packets can be lost to interference or corruption while the queue is nearly empty. A loss-based sender cannot tell the difference: - every random loss triggers a cut of 30-50%; - growth after the cut is slow on long paths, linear for Reno and a cubic curve for CUBIC; - the average window settles far below what the link could carry. The BBR draft quantifies it using RFC 9438's own model: over a 100 ms RTT path, a loss rate of 1% lets CUBIC sustain at most about 3 Mbps, whatever the link's capacity. RFC 9438 section 5.4 concedes that CUBIC's performance suffers in networks where packet loss is not a good indication of bandwidth utilization, naming wireless and mobile networks. ## Case 2: a deep-buffered link and bufferbloat Now give the bottleneck a very large buffer, as some last-mile equipment has. A loss-based sender sees no drop while the buffer absorbs its excess, so it keeps growing: 1. The link is already fully used once in-flight data reaches the path's bandwidth-delay product. 2. Everything beyond that sits in the buffer, adding queueing delay without adding throughput. 3. Only when the buffer overflows does a drop arrive and the sender cut back. 4. After the cut it climbs again and refills the buffer. The result is a **standing queue**: every flow through that bottleneck, including latency-sensitive traffic, waits behind it. The BBR draft calls this **bufferbloat**. RFC 9438 notes CUBIC fills large drop-tail buffers faster than Reno. Active queue management with ECN marking lets a router signal before the buffer is full, which shortens the queue but keeps the loss-equivalent reaction. ## How BBR reads the path instead BBR ("Bottleneck Bandwidth and Round-trip propagation time") is specified in `draft-ietf-ccwg-bbr-05`, an Internet-Draft with **Experimental** intended status, describing **BBRv3**. It is not an RFC. Rather than reacting to loss alone, it builds a **model**: - **`BBR.max_bw`**: a windowed maximum of measured delivery rate, the bottleneck bandwidth estimate. - **`BBR.min_rtt`**: the minimum RTT seen over the last 10 seconds, the propagation delay estimate. - **`BBR.bdp`** = bandwidth x `min_rtt`, the amount of data that fills the pipe without a queue. It then controls two things: a **pacing rate** near the estimated bandwidth, and a cap on in-flight data derived from the BDP. A state machine cycles through **Startup** (pacing gain about 2.77, so the rate roughly doubles per round), **Drain**, **ProbeBW** and **ProbeRTT**, which periodically cuts in-flight data for at least 200 ms, no more often than every 5 seconds, so that `min_rtt` can be re-measured without its own queue. | | Reno (RFC 5681) | CUBIC (RFC 9438) | BBRv3 (draft) | |---|---|---|---| | Main signal | loss, ECN | loss, ECN | delivery rate, RTT, loss rate | | Reduction | 0.5 | 0.7 | 0.7 per round with loss; caps in-flight data above a 2% loss rate | | Random low loss | cuts every time | cuts every time | tolerated below the threshold | | Deep buffer | fills it | fills it faster | aims to keep the queue small | | Status | Standards Track RFC | Standards Track RFC | Internet-Draft, Experimental intended | ## BBR is not loss-blind A common misreading is that BBR ignores loss. BBRv3 uses the **loss rate** as a model input: while probing, if a round trip sees loss above `BBR.LossThresh` (2%), it records that in-flight level as a long-term ceiling, and its multiplicative decrease factor `BBR.Beta` is 0.7 for rounds with loss. The draft also says any CE mark MUST be treated as congestion, though it specifies no particular ECN response. ## Caveats a senior answer mentions - The draft lists open issues, for example that BBR does not handle persistently application-limited traffic well. - Coexistence with Reno and CUBIC flows is an explicit design goal of the draft, because bandwidth probing can cause loss that hurts them. - The advantages on lossy and deep-buffered links are the draft's own claims for an Experimental specification.
- Does BBR ignore packet loss?No. BBRv3 in `draft-ietf-ccwg-bbr-05` uses the loss rate as a model input: if loss in a probing round exceeds `BBR.LossThresh` (2%), it caps in-flight data at that level, and it applies a 0.7 multiplicative decrease on rounds with loss. What it does not do is cut on every isolated drop, so low random loss leaves its rate intact.
- Would enabling ECN rescue CUBIC on the lossy wireless link?Not for the random losses. ECN (RFC 3168) lets a router mark a packet instead of dropping it when its queue builds, and the sender must react essentially as it would to a drop. That helps a deep-buffered bottleneck signal early, but a packet corrupted on the radio is still simply lost, and CUBIC still cuts.
- Why does BBR periodically reduce its own in-flight data in ProbeRTT?Its propagation-delay estimate, `BBR.min_rtt`, can only be measured when no queue is standing, and its own traffic may keep one. ProbeRTT drains in-flight data for at least 200 ms, no more often than every 5 seconds, so the estimate stays fresh; the draft puts the cost at roughly 2% of bandwidth.
saying these in an interview costs you the question
- Every packet loss proves the bottleneck queue overflowed.
- BBR ignores packet loss entirely and reacts only to round-trip time.
- Bigger router buffers always improve both TCP throughput and latency.
- BBR is a Standards Track RFC in the same way CUBIC is.
- CUBIC is delay-based, so it avoids filling deep buffers.