TCP Congestion Control Algorithm Evolution: From Tahoe to BBRv3 — Principles, Performance, and Linux Practice
TCP congestion control is a critical determinant of network transport performance and a cornerstone of internet stability. Whether it’s webpage loading speed in web services, smoothness of live video streaming, inter-container communication in cloud-native applications, or download efficiency in P2P transfers, all rely on TCP congestion control to coordinate bandwidth allocation. A single BitTorrent node, for example, may maintain hundreds of concurrent TCP connections, and choosing the wrong algorithm can severely degrade bandwidth utilization. Since Van Jacobson’s seminal 1988 paper at SIGCOMM, congestion control algorithms have evolved over nearly four decades — from heuristic loss-based methods to precise model-based measurement. This article covers 12 major congestion control algorithms, explaining their core ideas, strengths, weaknesses, and applicable scenarios, from Tahoe and Reno to CUBIC, BBR, and Copa.
Fundamentals of Congestion Control
All TCP congestion control algorithms work around the Congestion Window (CWND) — the maximum amount of unacknowledged data the sender can have in flight:
| |
This formula reveals two constraints on TCP throughput: the sender’s window (CWND) and the receiver’s window (Receiver Window), with the smaller of the two determining actual throughput. CWND is dynamically adjusted by the congestion control algorithm, while the receive window is determined by the receiver’s buffer size.
The core differences between algorithms manifest in three dimensions:
- CWND growth rate (slow start vs congestion avoidance) — determines connection startup and bandwidth probing efficiency
- Congestion detection signal (packet loss vs delay vs bandwidth measurement) — determines how the algorithm perceives network state
- Rate reduction strategy (multiplicative decrease vs model-driven adjustment) — determines recovery speed after congestion events
flowchart TD
A["Connection established<br/>CWND = IW"] --> B["Slow Start<br/>CWND doubles per RTT"]
B -->|"CWND ≥ ssthresh"| C["Congestion Avoidance<br/>CWND +1 MSS per RTT"]
C -->|"Packet loss / Timeout"| D{"Signal type"}
D -->|"3 duplicate ACKs"| E["Fast Retransmit + reduce"]
D -->|"Timeout"| F["CWND = 1<br/>restart Slow Start"]
E --> C
F --> B
style A fill:#2196F3,color:#fff
style B fill:#2196F3,color:#fff
style C fill:#4CAF50,color:#fff
style D fill:#9C27B0,color:#fff
style E fill:#FF9800,color:#fff
style F fill:#f44336,color:#fffTCP Tahoe (1988)
Van Jacobson’s 1988 SIGCOMM paper introduced the original congestion control framework, later known as TCP Tahoe. Tahoe defined three core phases:
- Slow Start: After connection establishment, CWND starts from an initial window (typically 10 segments) and increases by 1 MSS per ACK received, achieving exponential growth to quickly probe available bandwidth.
- Congestion Avoidance: Once CWND reaches the slow start threshold (ssthresh), it increases by only 1 MSS per RTT, shifting to linear growth for cautious bandwidth utilization.
- Fast Retransmit: Upon receiving 3 duplicate ACKs, the lost segment is retransmitted immediately without waiting for a timeout.
Tahoe’s limitation is that after packet loss, it falls back to slow start (CWND = 1 MSS), re-probing bandwidth from scratch every time. On high-bandwidth links, this results in significant bandwidth waste and lengthy recovery times. This flaw directly motivated the creation of Reno, which introduced fast recovery to avoid the inefficiency of restarting slow start after every loss.
TCP Reno (1990)
Reno added Fast Recovery on top of Tahoe, forming the complete AIMD (Additive Increase Multiplicative Decrease) model. Its core philosophy can be summarized in one sentence: increase linearly under light load, back off exponentially when congestion is detected.
flowchart TD
SS["Slow Start<br/>CWND = IW<br/>Exponential growth"] -->|"CWND ≥ ssthresh"| CA["Congestion Avoidance<br/>+1 MSS per RTT<br/>Linear growth"]
CA -->|"Packet loss"| LOSS{"Signal type"}
LOSS -->|"3 duplicate ACKs"| FR["Fast Recovery<br/>ssthresh = CWND/2"]
LOSS -->|"Timeout"| TO["Timeout<br/>ssthresh = CWND/2<br/>CWND = 1"]
FR -->|"New ACK"| CA
TO --> SS
style SS fill:#2196F3,color:#fff
style CA fill:#4CAF50,color:#fff
style LOSS fill:#9C27B0,color:#fff
style FR fill:#FF9800,color:#fff
style TO fill:#f44336,color:#fffDuring slow start, Reno exponentially probes available bandwidth — each ACK received increments CWND by one MSS (Maximum Segment Size), effectively doubling it every RTT. When CWND reaches the slow start threshold (ssthresh), it transitions to congestion avoidance, incrementing by only 1 MSS per RTT for linear growth. Upon detecting packet loss (three duplicate ACKs), it immediately halves ssthresh to CWND/2, sets CWND to ssthresh, and enters fast recovery.
Reno’s limitation: Conservative on high-bandwidth high-latency paths. Consider a link with 100ms RTT and 1Gbps bandwidth — BDP is approximately 12.5MB. After a single packet loss, CWND halves and requires thousands of RTTs to recover to its original size, meaning several minutes of recovery time with severe bandwidth waste.
TCP Vegas (1994)
Vegas, proposed by Brakmo and Peterson, was the first delay-based congestion control algorithm, marking the transition from reactive to predictive congestion control.
Vegas estimates network queuing by monitoring RTT changes, proactively adjusting the sending rate before packet loss occurs. It maintains two key measurements: BaseRTT (the minimum observed RTT, representing no queuing delay) and CurrentRTT (the currently measured RTT). It detects congestion by comparing the difference between expected and actual throughput:
$$ Diff = \left(\frac{CWND}{BaseRTT} - \frac{CWND}{CurrentRTT}\right) \times BaseRTT $$When Diff falls below threshold α, bandwidth is considered abundant and CWND is increased. When Diff exceeds threshold β, congestion is anticipated and CWND is decreased. Typical values for α and β are 2 and 4, respectively.
flowchart TD
A["Measure RTT<br/>BaseRTT / CurrentRTT"] --> C["Compute Diff<br/>= CWND/BaseRTT − CWND/CurrentRTT"]
C --> D{"Diff value"}
D -->|"Diff < α"| E["Bandwidth abundant<br/>CWND += 1"]
D -->|"α ≤ Diff ≤ β"| F["Stable zone<br/>CWND held"]
D -->|"Diff > β"| G["Congestion imminent<br/>CWND −= 1"]
style A fill:#2196F3,color:#fff
style C fill:#FF9800,color:#fff
style D fill:#9C27B0,color:#fff
style E fill:#4CAF50,color:#fff
style F fill:#FF9800,color:#fff
style G fill:#f44336,color:#fffVegas’ innovation lies in its forward-looking congestion avoidance — it reacts as soon as queuing begins, rather than waiting for buffer overflow and packet loss. Under ideal conditions, this maintains extremely low queuing delay and avoids the characteristic “sawtooth” oscillation of traditional AIMD algorithms.
However, when sharing a bottleneck link with loss-based algorithms like Reno or CUBIC, Vegas behaves too “politely” — it gives up bandwidth due to the minor queuing delay it introduces, allowing aggressive loss-based flows to take over. This compatibility issue has severely limited Vegas’ real-world deployment.
TCP NewReno (1996)
NewReno, proposed by Floyd and Henderson, is a targeted improvement to Reno’s fast recovery mechanism, specifically addressing performance issues when multiple packets are lost within a single window.
Reno’s fast recovery has a flaw: when multiple packets are lost in the same window, the first new ACK received during fast recovery (acknowledging the first retransmitted packet) causes Reno to exit fast recovery, even though other lost packets remain unretransmitted. This forces Reno to enter and exit fast recovery repeatedly, fixing only one loss at a time.
NewReno’s key improvement is Partial ACK detection logic: if the ACK received during fast recovery acknowledges only a portion of the outstanding data (a partial ACK), NewReno does not exit fast recovery. Instead, it immediately retransmits the next lost packet while keeping CWND unchanged. It only exits fast recovery when an ACK acknowledges all data that was outstanding when fast recovery began.
flowchart TD
A["3 duplicate ACKs<br/>enter Fast Recovery"] --> B["Retransmit lost packet"]
B --> C{"ACK received?"}
C -->|"Partial ACK<br/>data still unacknowledged"| D["Retransmit next lost packet<br/>stay in Fast Recovery"]
D --> C
C -->|"Full ACK<br/>all data acknowledged"| E["Exit Fast Recovery<br/>enter Congestion Avoidance"]
style A fill:#2196F3,color:#fff
style B fill:#FF9800,color:#fff
style C fill:#9C27B0,color:#fff
style D fill:#FF9800,color:#fff
style E fill:#4CAF50,color:#fffThis improvement makes NewReno significantly outperform Reno on links with random packet loss, and it requires no modifications to the receiver — it is a fully sender-side improvement. NewReno was later standardized as RFC 2582 (later updated by RFC 3782).
TCP Westwood+ (2002)
Westwood+, proposed by Mascolo and colleagues, specifically addresses the throughput degradation caused by random packet loss in wireless networks. Its core idea is to use bandwidth estimation rather than simple loss signals to adjust the congestion window.
Westwood+ continuously estimates available bandwidth by monitoring ACK arrival rates. When packet loss is detected, instead of Reno’s brute-force halving of CWND, it calculates a new window value based on the estimated bandwidth:
$$ ssthresh = \frac{BWEst \times RTT_{min}}{MSS} $$This bandwidth-aware rate reduction strategy excels on wireless links with random packet loss — when packet loss is caused by channel noise rather than congestion, the bandwidth estimate does not drop significantly, preventing excessive CWND reduction.
The original Westwood used only sender-side measurements. Westwood+ added receiver-side ACK filtering to eliminate the effects of ACK Compression, making bandwidth estimation more accurate.
BIC (2004)
BIC (Binary Increase Congestion Control), proposed by Xu, Harfoush, and Rhee, was designed for high-bandwidth long-distance networks and is the predecessor of CUBIC.
BIC uses binary search to find the bandwidth boundary. When congestion occurs, the current window $W_{max}$ is recorded. During recovery, binary search is performed between $W_{min}$ (the post-congestion window value) and $W_{max}$, quickly approaching but not exceeding the previous window ceiling. Above $W_{max}$, a Max Probing strategy gradually expands the search range to discover new bandwidth limits.
BIC performs well in high BDP networks but has two notable problems: first, its window function shape is not smooth — the piecewise binary search causes window oscillations at transition points; second, it is too aggressive in low-bandwidth networks, lacking friendliness when coexisting with traditional algorithms like Reno. These issues motivated the design of CUBIC.
TCP Hybla (2004)
Hybla, proposed by Caini and Firrincieli, is specifically designed for long-RTT links such as satellite communications.
Hybla’s core observation is that in traditional TCP, connections with long RTTs have much slower window growth during congestion avoidance compared to short-RTT connections. Hybla compensates for this unfairness by introducing an “RTT normalization” factor, simulating the behavior of an ideal reference connection so that long-RTT flows achieve equivalent window growth rates to short-RTT flows.
In extreme scenarios like GEO satellite links (RTT ≈ 500ms), Hybla can improve throughput by several times over standard Reno. Its main limitation is that parameter selection depends on prior knowledge of the link type, making it less effective in environments with dynamically changing link characteristics.
TCP CUBIC (2005)
CUBIC is currently the default congestion control algorithm in the Linux kernel, proposed by Injong Rhee and colleagues, specifically designed to address Reno’s inefficiency in high BDP (Bandwidth-Delay Product) networks.
Cubic Growth Function
CUBIC’s most fundamental innovation is using a cubic function to drive window growth:
$$W(t) = C \times (t - K)^3 + W_{max}$$Where $t$ is the time elapsed since the last congestion event, $W_{max}$ is the window size at the time of congestion, $C$ is a scaling constant (default 0.4), and $K = \sqrt[3]{W_{max} \times \beta / C}$ is the time needed for the window to recover to $W_{max}$.
flowchart TD
B["W(t) = C×(t−K)³ + Wmax<br/>t = time since last loss"] --> D{"Window Position"}
D -->|"Below Wmax"| E["Concave growth<br/>Fast catch-up"]
D -->|"Above Wmax"| G["Convex growth<br/>Probe new ceiling"]
E --> H{"Packet loss?"}
G --> H
H -->|"Yes"| I["CWND × 0.7<br/>Record new Wmax"]
I --> B
style B fill:#2196F3,color:#fff
style D fill:#9C27B0,color:#fff
style E fill:#4CAF50,color:#fff
style G fill:#FF9800,color:#fff
style H fill:#9C27B0,color:#fff
style I fill:#f44336,color:#fffThree Key Properties of CUBIC
CUBIC’s core idea is to use time rather than ACK arrivals to drive window growth, making the growth rate independent of RTT:
- Concave growth: Fast recovery far below $W_{max}$. After a loss event, CUBIC’s window function rises sharply, quickly pulling CWND back to pre-congestion levels — precisely where Reno performs worst.
- Convex growth: Active probing above $W_{max}$. Once CWND exceeds the previous congestion window value, the function curve accelerates, actively searching for new bandwidth ceilings.
- RTT fairness: Flows with different RTTs achieve similar window increments over a fixed time period. In Reno, short-RTT flows grow their congestion windows faster and can “starve” long-RTT flows. CUBIC eliminates this RTT bias.
Why CUBIC Replaced BIC
CUBIC’s predecessor was BIC (Binary Increase Congestion Control), which used binary search to probe bandwidth boundaries — it performed well in high-bandwidth networks but was too aggressive in low-bandwidth scenarios, and its window function shape was not smooth. CUBIC replaced BIC’s piecewise binary search with a smooth cubic function, preserving high BDP efficiency while improving friendliness in low-bandwidth networks.
DCTCP (2010)
DCTCP (Data Center TCP), proposed by Alizadeh and colleagues, is purpose-built for data center networks. Data centers are characterized by high bandwidth (10Gbps-40Gbps), low latency (microseconds), limited buffers, and traffic patterns dominated by short bursts.
DCTCP’s core innovation is fine-grained congestion control using ECN (Explicit Congestion Notification) signals. Switches mark packets when the queue length exceeds a threshold, the receiver computes the fraction of marked packets $F$, and the sender calculates a congestion factor $\alpha$:
$$ \alpha = (1 - g) \times \alpha + g \times F $$Where $g$ is a smoothing factor (default 1/16). When congestion occurs, CWND is set to $CWND \times (1 - \alpha/2)$, rather than being brutally halved. The more severe the congestion, the more aggressive the reduction; the milder the congestion, the gentler the reduction.
flowchart TD
A["Queue > threshold<br/>Switch marks ECN"] --> C["Receiver computes marked fraction F"]
C --> D["Sender updates congestion factor<br/>α = (1−g)α + gF"]
D --> E{"On congestion"}
E -->|"Mild α small"| F["CWND × (1−α/2)<br/>slight reduction"]
E -->|"Severe α large"| G["CWND × (1−α/2)<br/>large reduction"]
style A fill:#2196F3,color:#fff
style C fill:#FF9800,color:#fff
style D fill:#FF9800,color:#fff
style E fill:#9C27B0,color:#fff
style F fill:#4CAF50,color:#fff
style G fill:#f44336,color:#fffDCTCP’s remarkable achievement is the ideal combination of low latency + high throughput — in production environments, DCTCP reduces tail latency by over 90% while maintaining close to 100% link utilization. However, DCTCP depends on switch ECN support and is only suitable for controlled data center environments.
BBR’s Paradigm Revolution (2016)
Google’s 2016 release of BBR (Bottleneck Bandwidth and Round-trip propagation time) fundamentally changed the traditional paradigm of congestion control. The core insight: Packet loss is not equivalent to congestion.
In wireless networks, cellular networks, and similar environments, packets may be lost due to signal interference or channel attenuation — not because the network link is congested. Traditional loss-based algorithms mistakenly reduce their sending rate in such cases, causing severe bandwidth waste.
| Dimension | Traditional loss-based (Reno / CUBIC) | BBR (model-driven) |
|---|---|---|
| Signal | Packet loss | Bandwidth + RTT |
| Assumption | Loss = congestion | Measure BtlBw + RTprop |
| Action | Loss → slow down | Operate at BDP point |
| On lossy links | Bandwidth utilization drops sharply | Maintains high throughput |
Packet loss ≠ congestion is BBR’s starting point: on wireless networks packets are frequently lost to signal interference, and slowing down in response is pure waste.
BBR’s Key Innovations
- Loss-independent: Maintains high throughput even with up to 15% packet loss, while CUBIC’s throughput drops dramatically at just 1% loss.
- Proactive BDP estimation: By measuring bottleneck bandwidth (BtlBw) and propagation delay (RTprop), BBR calculates the optimal amount of data for the link and operates at the BDP point — neither queuing nor wasting capacity.
- Bufferbloat avoidance: BBR does not fill up buffers even when they are large, avoiding excessive queuing delay — critical for latency-sensitive applications such as real-time audio/video and online gaming.
BBR Version Evolution
Since its initial release, BBR has gone through three major versions:
| Version | Year | Core Improvements |
|---|---|---|
| BBR v1 | 2016 | First model-based congestion control, achieving high throughput with low latency; suffered from poor coexistence fairness with Reno/CUBIC and high packet loss during STARTUP |
| BBR v2 | 2019 | Added ECN signal support, improved fairness when coexisting with Reno/CUBIC, reduced STARTUP phase packet loss |
| BBR v3 | 2023 | Fixed bandwidth convergence bugs, reduced STARTUP gain from 2.89 to 2.77, further decreased queuing delay, optimized short-flow performance |
Key Drivers of Version Evolution
BBR’s version evolution reflects the deepening understanding of “ideal congestion control” in both academia and industry:
- Coexistence fairness: BBR v1 was too aggressive when sharing a bottleneck link with other algorithms, preempting CUBIC flows’ bandwidth. v2 and v3 progressively improved this through more conservative contention strategies.
- STARTUP oscillation: The initial version’s exponential gain during STARTUP was too high (2.89), causing frequent over-probing and packet loss. v3 reduced the gain to 2.77, significantly reducing startup oscillation.
- Bandwidth convergence: In multi-flow bottleneck sharing scenarios, v1 and v2 suffered from unstable bandwidth allocation. v3 achieved faster and more stable convergence through algorithmic optimization.
PCC (2016)
PCC (Performance-oriented Congestion Control), proposed by Dong and colleagues, was released in the same year as BBR but takes a fundamentally different approach — framing congestion control as an online learning problem.
PCC makes no prior assumptions about congestion signals (whether loss, delay, or bandwidth), instead directly optimizing the sending rate through experimentation. Its core is a Monitor-Compare-Arrange loop: the sender slightly adjusts the sending rate in one direction (+Δt), observes utility changes; then adjusts in the other direction (-Δt), compares results, and continues in the direction that yields better performance.
flowchart TD
A["Current rate r"] --> B["Try r + Δ<br/>measure utility U⁺⁺"]
B --> C["Try r − Δ<br/>measure utility U⁻"]
C --> D{"U⁺⁺ > U⁻?"}
D -->|"Yes"| E["Raise rate"]
D -->|"No"| F["Lower rate"]
E --> A
F --> A
style E fill:#4CAF50,color:#fff
style F fill:#f44336,color:#fffPCC’s utility function combines throughput and latency metrics:
$$ U = \frac{Throughput^{\alpha}}{Latency^{\beta}} $$The advantage of this approach is that it requires no assumptions about network behavior, automatically adapting to various link conditions. However, it has higher computational overhead and may converge more slowly. The subsequent PCC Vivace improved convergence speed by introducing an online gradient ascent algorithm.
Copa (2018)
Copa, proposed by Arun and Balakrishnan, is the latest generation of delay-aware congestion control. It returns to Vegas’ delay-probing approach but employs a more sophisticated “Carrier Sensing” mechanism.
Copa dynamically adjusts the sending rate by sensing queuing delay $d_{queued}$. Its core parameter $\lambda$ determines the CWND increase per ACK:
flowchart TD
A["Measure queuing delay<br/>d = RTT − BaseRTT"] --> B["Compute growth rate<br/>λ = δ / d"]
B --> C{"d < target delay?"}
C -->|"Yes, low delay"| D["CWND += λ<br/>accelerate growth"]
C -->|"No, high delay"| E["CWND −= λ<br/>actively yield"]
style D fill:#4CAF50,color:#fff
style E fill:#FF9800,color:#fffWhere $\delta$ is a parameter (default 0.5). When queuing delay increases, $\lambda$ decreases, slowing window growth; when queuing delay decreases, $\lambda$ increases, accelerating growth. Copa aims to maintain a fixed queuing delay target (typically corresponding to 5 RTTs of queuing).
Copa’s elegance lies in achieving smooth congestion control by adjusting the growth rate rather than mechanically raising or lowering the window. In benchmarks, Copa matches or exceeds BBR in throughput while maintaining lower latency. It also includes a competitive mode that prevents starvation when coexisting with aggressive flows like CUBIC.
TCP Congestion Control Evolution Timeline
From 1988 to 2023, TCP congestion control algorithms have evolved from simple beginnings to sophisticated designs. The two timelines below illustrate the development of major algorithms:
Early Era (1988—2004)
flowchart TD
T["1988: Tahoe<br/>Slow Start + CA<br/>Fast Retransmit"]
R["1990: Reno<br/>+ Fast Recovery<br/>AIMD Classic"]
V["1994: Vegas<br/>Delay probing<br/>Predict congestion"]
N["1996: NewReno<br/>Partial ACK<br/>Multi-loss fix"]
W["2002: Westwood+<br/>BW estimation<br/>Wireless friendly"]
B["2004: BIC<br/>Binary search<br/>High BDP efficiency"]
T --> R
R --> N
R --> V
N --> B
V --> W
style T fill:#2196F3,color:#fff
style R fill:#2196F3,color:#fff
style V fill:#9C27B0,color:#fff
style N fill:#FF9800,color:#fff
style W fill:#4CAF50,color:#fff
style B fill:#f44336,color:#fffModern Era (2004—2023)
flowchart TD
H["2004: Hybla<br/>Satellite optimized<br/>RTT normalization"]
C["2005: CUBIC<br/>Cubic function<br/>RTT independent"]
D["2010: DCTCP<br/>Data center<br/>ECN marking"]
P["2016: PCC<br/>Performance-driven<br/>Online learning"]
BR["2016: BBR v1-3<br/>Model-driven<br/>BtlBw+RTprop"]
O["2018: Copa<br/>Delay-aware<br/>Carrier sensing"]
H --> C
C --> D
D --> P
C --> BR
BR --> O
style H fill:#2196F3,color:#fff
style C fill:#2196F3,color:#fff
style D fill:#FF9800,color:#fff
style P fill:#9C27B0,color:#fff
style BR fill:#4CAF50,color:#fff
style O fill:#9C27B0,color:#fffThese timelines clearly reveal the trajectory of congestion control evolution: from loss-based reactive control, to delay-based predictive control, and finally to model-driven and performance-driven intelligent control. This evolution reflects the technological demands of a changing internet — from simple wired networks to complex heterogeneous environments.
Linux Practical: View and Switch Algorithms
Now that we understand the theory, let’s explore how to work with congestion control algorithms on a real Linux system. The following commands let you view and switch the algorithm:
| |
Example output:
| |
If bbr does not appear in the output, the BBR kernel module has not been loaded. You can load it manually:
| |
Note that changing the congestion control algorithm is a system-wide operation — all new TCP connections will use the new algorithm. Established connections continue using the algorithm they were created with and are unaffected by the switch.
With the advent of eBPF technology, Linux also supports user-defined congestion control algorithms via BPF (BPF_PROG_TYPE_SOCK_OPS), offering new flexibility for congestion control research and deployment.
Performance Comparison
Throughput on Lossy Links
The performance gap between congestion control algorithms becomes stark on lossy links. The following table shows throughput comparison under identical network conditions (100ms RTT, 100Mbps bandwidth):
| Packet Loss Rate | Reno | CUBIC | BBR |
|---|---|---|---|
| 0% | 100% | 100% | 100% |
| 0.1% | ~50% | ~85% | ~99% |
| 1% | ~10% | ~30% | ~95% |
| 3% | ~3% | ~12% | ~88% |
| 5% | ~1% | ~5% | ~80% |
| 10% | ~0.5% | ~2% | ~60% |
The data reveals a clear picture:
- At 0.1% loss rate, CUBIC maintains about 85% throughput, but Reno has already lost half its bandwidth.
- At 1% loss rate, CUBIC drops to ~30%, while BBR still maintains over 95% throughput — this is the typical loss range for wireless and cellular networks.
- At 5% loss rate, Reno and CUBIC are practically unusable, while BBR still delivers about 80% throughput.
This explains why some network applications — such as P2P transfers and video streaming — often suffer from poor transport performance on wireless networks. It is not just the application-layer protocol at fault; the underlying TCP congestion control algorithm plays an equally critical role.
Algorithm Characteristics Comparison
Different congestion control algorithms vary significantly in their congestion signals, applicable scenarios, and design philosophies:
| Algorithm | Year | Type | Core Congestion Signal | Applicable Scenario |
|---|---|---|---|---|
| Tahoe | 1988 | Loss-based | Dup ACK / Timeout | Historical reference |
| Reno | 1990 | Loss-based | Dup ACK | Low bandwidth, low latency |
| Vegas | 1994 | Delay-based | RTT variation | Low-latency networks |
| NewReno | 1996 | Loss-based | Partial ACK | Moderate loss links |
| Westwood+ | 2002 | BW estimation | ACK rate + Loss | Wireless networks |
| BIC | 2004 | Loss-based | Dup ACK | High BDP networks |
| Hybla | 2004 | Loss-based | RTT normalization | Satellite links |
| CUBIC | 2005 | Loss-based | Dup ACK (time-driven) | Linux default / general |
| DCTCP | 2010 | Hybrid | ECN marking ratio | Data center |
| BBR v3 | 2016 | Model-based | BtlBw + RTprop | High throughput / wireless |
| PCC | 2016 | Performance-driven | Utility function | General / complex links |
| Copa | 2018 | Delay-based | Queuing delay | General / low latency |
As the diversity of algorithm types and applicable scenarios demonstrates, there is no single “best” congestion control algorithm — the right choice depends on the specific network environment, application requirements, and deployment constraints.
References
- Jacobson, V. (1988). Congestion avoidance and control. SIGCOMM ‘88.
- Brakmo, L. S., & Peterson, L. L. (1995). TCP Vegas: End to end congestion avoidance on a global Internet. IEEE Journal on Selected Areas in Communications, 13(8).
- Floyd, S., & Henderson, T. (1999). The NewReno modification to TCP’s fast recovery algorithm. RFC 2582.
- Mascolo, S., et al. (2001). TCP Westwood: Bandwidth estimation for enhanced transport over wireless links. MobiCom ‘01.
- Xu, L., Harfoush, K., & Rhee, I. (2004). Binary increase congestion control (BIC) for fast long-distance networks. INFOCOM 2004.
- Caini, C., & Firrincieli, R. (2004). TCP Hybla: a TCP enhancement for heterogeneous networks. International Journal of Satellite Communications and Networking, 22(5).
- Ha, S., Rhee, I., & Xu, L. (2008). CUBIC: a new TCP-friendly high-speed TCP variant. ACM SIGOPS Operating Systems Review, 42(5).
- Alizadeh, M., et al. (2010). Data Center TCP (DCTCP). SIGCOMM ‘10.
- Cardwell, N., et al. (2016). BBR: Congestion-based congestion control. ACM Queue, 14(5).
- Dong, M., et al. (2015). PCC: Re-architecting congestion control for consistent high performance. NSDI ‘15.
- Arun, V., & Balakrishnan, H. (2018). Copa: Practical delay-based congestion control for the internet. NSDI ‘18.
- Cardwell, N., et al. (2022). BBR Congestion Control (IETF Draft). https://datatracker.ietf.org/doc/draft-cardwell-iccrg-bbr-congestion-control/