rfc-9438

CUBIC for Fast and Long-Distance Networks

L. Xu, S. Ha, I. Rhee, V. Goel, L. Eggert (Editor)
date2023-08 streamIETF areawit wgtcpm statusPROPOSED STANDARD pages28 canonicalhttps://www.rfc-editor.org/rfc/rfc9438 doi10.17487/RFC9438
CUBIC is a standard TCP congestion control algorithm that uses a cubic function instead of a linear congestion window increase function to improve scalability and stability over fast and long-distance networks. CUBIC has been adopted as the default TCP congestion control algorithm by the Linux, Windows, and Apple stacks. This document updates the specification of CUBIC to include algorithmic improvements based on these implementations and recent academic work. Based on the extensive deployment experience with CUBIC, this document also moves the specification to the Standards Track and obsoletes RFC 8312. This document also updates RFC 5681, to allow for CUBIC's occasionally more aggressive sending behavior.

obsoletes

updates

Extracted elements (29)

design-rationale §5.1

C=0.4 was chosen based on the observation that at RTT=0.01s CUBIC with C≤0.4 achieves exactly the same average window as Reno (Reno-friendly), while C=4 becomes more aggressive. Tables 1–2 show CUBIC with C=0.4 is substantially more Reno-friendly than HSTCP across all tested loss rates.

congestion, tcp

design-rationale §5.8

CUBIC does not increase its congestion window if a flow is application-limited. The time variable t in W_cubic(t) explicitly excludes idle or rate-limited periods; otherwise, W_cubic would be unreasonably high after restarting, causing overshoot.

congestion, tcp

design-rationale §3.2

CUBIC is designed to behave like Reno in networks with short RTTs and small BDPs (the Reno-friendly region). When the cubic function would increase cwnd less aggressively than Reno, CUBIC simply follows Reno's window size, ensuring at least the same throughput as Reno in those environments.

congestion, tcp

design-rationale §3.4

CUBIC sets β_cubic to 0.7 rather than Reno's 0.5 to balance scalability and convergence speed. The higher value improves scalability but slows convergence under low statistical multiplexing; this tradeoff is acceptable because the modern Internet is more asynchronous with less frequent loss synchronizations under high multiplexing.

congestion, tcp

design-rationale §3.1

CUBIC uses both the concave and convex profiles of a cubic function for window growth rather than a purely convex increase. This keeps the window nearly constant around the remembered W_max, promoting stability and high utilization while avoiding the packet bursts at the saturation point that purely convex functions cause.

congestion, tcp

interoperability-note §5.4

As a loss-based algorithm, CUBIC suffers in networks where packet loss is not a good indicator of bandwidth utilization, such as wireless or mobile networks. CUBIC can also fill large drop-tail buffers more quickly than Reno; proper queue sizing and AQM (RFC 7567) can mitigate this.

congestion, tcp

interoperability-note §1

CUBIC can also be used as a default congestion controller for other transport protocols such as QUIC (RFC 9000) and SCTP (RFC 9260), not only for TCP.

congestion, tcp, quic

interoperability-note §5.10

CUBIC requires only sender-side changes and works correctly with Reno receivers. It does not require any changes at receivers or routers, making incremental deployment straightforward.

congestion, tcp

interoperability-note §1

This document updates RFC 5681 Section 3 by replacing the restriction limiting cwnd increments to at most SMSS per RTT with a normative reference to RFC 5033 guideline (1), which permits CUBIC's occasionally more aggressive cwnd increases during congestion avoidance and slow start.

congestion, tcp

normative-requirement §4.6 REQUIRED

A QUIC sender that uses a cwnd value (rather than flight_size) to calculate new cwnd and ssthresh after detecting a congestion event is REQUIRED to apply similar mechanisms as defined in RFC 9002.

congestion, quic

normative-requirement §5.1 SHOULD

C SHOULD be set to 0.4 to balance Reno-friendliness and aggressiveness of window increase. It is NOT RECOMMENDED to set C to a very low value such as 0.04, as CUBIC with a low C cannot efficiently use bandwidth in fast and long-distance networks.

congestion, tcp

normative-requirement §4.6 MUST

CUBIC MUST continue to reduce cwnd in response to ECN-Echo ACKs until cwnd reaches 1 SMSS. If congestion persists at cwnd = 1 SMSS, the sender MUST reduce its sending rate further using a retransmission timer with exponential backoff.

congestion, tcp

normative-requirement §4.7 SHOULD

Fast convergence SHOULD be implemented in multi-flow environments. In environments with only a single CUBIC flow and no other traffic, fast convergence SHOULD be disabled.

congestion, tcp

normative-requirement §4.6 MUST

Implementations using cwnd (rather than flight_size) to calculate new ssthresh MUST use other measures to prevent cwnd from growing when bytes in flight is smaller than cwnd, to avoid using an arbitrarily high cwnd when congestion is detected.

congestion, tcp

normative-requirement §4.4 MUST

In the concave region (cwnd < W_max, not Reno-friendly), cwnd MUST be incremented by (target − cwnd) / cwnd for each received new ACK, where target is W_cubic(t + RTT) as computed in Section 4.2.

congestion, tcp

normative-requirement §4.5 MUST

In the convex region (cwnd ≥ W_max, not Reno-friendly), cwnd MUST be incremented by (target − cwnd) / cwnd for each received new ACK. This "maximum probing phase" very slowly probes for a new W_max.

congestion, tcp

normative-requirement §4.2 MUST NOT

The elapsed time t in W_cubic(t) MUST NOT include periods during which cwnd has not been updated due to application-limited behavior, to prevent an artificially inflated target after idle periods.

congestion, tcp

normative-requirement §4.6 MUST

Upon detecting packet loss, the sender MUST reduce cwnd and ssthresh immediately upon entering loss recovery. β_cubic SHOULD be set to 0.7; ssthresh = flight_size * β_cubic, and cwnd is reduced to max(ssthresh, 2) on loss or max(ssthresh, 1) on ECN-Echo.

congestion, tcp

normative-requirement §4.10 MUST

When cwnd ≤ ssthresh, CUBIC MUST employ a slow start algorithm. CUBIC SHOULD use HyStart++ (RFC 9406) or MAY use Reno slow start in rare cases where HyStart++ is not suitable.

congestion, tcp

normative-requirement §4.3 SHOULD

When W_cubic(t) < W_est (the Reno-friendly region), cwnd SHOULD be set to W_est at each reception of a new ACK during congestion avoidance.

congestion, tcp

protocol-element §4.7

Fast convergence: when a congestion event occurs and cwnd < W_max (indicating the saturation point is shrinking), W_max is further reduced to cwnd*(1+β_cubic)/2 before applying the multiplicative decrease, lengthening the time this flow needs to recover and giving new flows more room to grow.

congestion, tcp

protocol-element §4.9.2

For spurious fast retransmits, a CUBIC implementation MAY save state (cwnd, cwnd_prior, ssthresh, W_max, K, t_epoch, W_est) before reducing the window. If the loss is confirmed spurious and current cwnd < cwnd_prior, these saved values MAY be restored to recover performance.

congestion, tcp

protocol-element §4.3

In the Reno-friendly region, W_est estimates the Reno congestion window via W_est += α_cubic * (segments_acked / cwnd), where α_cubic = 3*(1−β_cubic)/(1+β_cubic). Once W_est ≥ cwnd_prior, α_cubic SHOULD be set to 1 to match Reno's AIMD(1, 0.5) increment rate.

congestion, tcp

protocol-element §4.2

K is computed as the cube root of (W_max − cwnd_epoch) / C, representing the time needed to grow from the congestion-avoidance starting window back to W_max. Upon a timeout, K is set to 0 and W_max is set to cwnd at the start of the congestion avoidance stage.

congestion, tcp

protocol-element §4.2

On each new ACK in congestion avoidance, target = W_cubic(t+RTT) bounded below by cwnd (non-decreasing) and above by 1.5*cwnd (below the slow-start rate). CUBIC then picks the maximum of W_cubic(t) and W_est as the effective window.

congestion, tcp

protocol-element §4.8

On timeout, CUBIC follows Reno's cwnd reduction but sets ssthresh using β_cubic. The subsequent congestion avoidance uses W_cubic(t) with K=0 and W_max = cwnd at the start of congestion avoidance; W_est is also initialized to that cwnd for the Reno-friendly region.

congestion, tcp

protocol-element §4.2

The CUBIC window increase function is W_cubic(t) = C*(t−K)^3 + W_max, where t is elapsed time from the start of the current congestion avoidance stage, K is the time to grow back to W_max, C is the aggressiveness constant, and W_max is the window at the last congestion event.

congestion, tcp, quic

protocol-element §4.10

When CUBIC exits the first slow start via HyStart++ without packet loss, W_max is undefined; CUBIC sets cwnd_prior = cwnd, switches to congestion avoidance, and uses W_cubic(t) with K=0 and W_max set to the congestion window at the start of congestion avoidance.

congestion, tcp

security-consideration §6

CUBIC makes no changes to the underlying security of a transport protocol and inherits the general security concerns of RFC 5681. An attacker can drop or inject ACKs to force the CUBIC implementation to reduce its bandwidth or to mask congestion; these attacks are not new to CUBIC and are inherent to TCP.

security, congestion, tcp