rfc-9002

QUIC Loss Detection and Congestion Control

J. Iyengar (Editor), I. Swett (Editor)
date2021-05 streamIETF areawit wgquic statusPROPOSED STANDARD pages42 canonicalhttps://www.rfc-editor.org/rfc/rfc9002 doi10.17487/RFC9002 errataview
This document describes loss detection and congestion control mechanisms for QUIC.

Extracted elements (31)

design-rationale §7.6.1

Persistent congestion is detected using a time duration rather than consecutive PTO events, because application send patterns can prevent PTO timers from expiring even when no acknowledgments are received. A duration-based approach allows persistent congestion to be established independently of PTO expiration.

quic, congestion

design-rationale §4.8

QUIC recommends a minimum congestion window of two packets rather than TCP's one. With a one-packet minimum, loss forces the sender to wait for a PTO to recover, and sending a single ack-eliciting packet increases the chance of additional latency from receiver-delayed acknowledgments.

quic, congestion

design-rationale §4.7

QUIC uses a Probe Timeout (PTO) instead of TCP's RTO and TLP. Unlike TCP's RTO, QUIC does not collapse the congestion window on PTO expiration since a single tail loss does not indicate persistent congestion, avoiding the need for corrective mechanisms like F-RTO. The congestion window collapses only when persistent congestion is declared.

quic, congestion

design-rationale §4.2

QUIC uses monotonically increasing packet numbers within each packet number space, directly encoding transmission order and eliminating TCP's retransmission ambiguity problem. This enables more accurate RTT measurements and allows spurious retransmissions to be trivially detected without complex inference of transmission ordering.

quic, congestion

design-rationale §4.1

QUIC uses separate packet number spaces per encryption level (except 0-RTT and 1-RTT share a space) to prevent acknowledgments at one encryption level from spuriously triggering retransmissions at another. RTT measurement and congestion control are unified across all packet number spaces.

quic, congestion

normative-requirement §6.2.2.1 MUST

A client MUST set the PTO timer if it has not received an acknowledgment for any Handshake packets and the handshake is not confirmed, even with no packets in flight, to unblock the server constrained by its anti-amplification limit. On PTO fire it MUST send a Handshake packet if it has Handshake keys, otherwise an Initial packet padded to at least 1200 bytes.

quic, congestion

normative-requirement §6.2 MUST NOT

A PTO timer expiration event MUST NOT cause prior unacknowledged packets to be marked as lost; it only triggers sending of probe packets. Loss detection from packet and time thresholds proceeds only when an acknowledgment is received.

quic, congestion

normative-requirement §5.3 MUST

After handshake confirmation, an endpoint MUST use the lesser of the ACK delay and the peer's max_ack_delay when adjusting RTT samples, and MUST NOT subtract the ACK delay if it would make the adjusted sample smaller than min_rtt, limiting underestimation from a misreporting peer.

quic, congestion

normative-requirement §7 MUST NOT

An endpoint MUST NOT send a packet if it would cause bytes_in_flight to exceed the congestion window, except when sending on PTO timer expiration or when entering recovery.

quic, congestion

normative-requirement §6.2.1 MUST NOT

An endpoint MUST NOT set its PTO timer for the Application Data packet number space until the handshake is confirmed, preventing retransmission of data before either peer has keys to process the packets or their acknowledgments.

quic, congestion

normative-requirement §5.1 MUST NOT

An RTT sample MUST NOT be generated on receiving an ACK frame that does not newly acknowledge at least one ack-eliciting packet, to avoid incorporating arbitrarily large ACK Delay values from ACKs covering only non-ack-eliciting packets.

quic, congestion

normative-requirement §7.2 SHOULD

Endpoints SHOULD use an initial congestion window of ten times the maximum datagram size, limited to the larger of 14,720 bytes or twice the maximum datagram size, per RFC 6928 with the byte limit increased to account for UDP's 8-byte versus TCP's 20-byte overhead.

quic, congestion

normative-requirement §7 MUST

If a sender uses a different congestion controller than the NewReno algorithm specified in this document, the chosen controller MUST conform to the congestion control guidelines in Section 3.1 of RFC 8085.

quic, congestion

normative-requirement §6.1.1 SHOULD NOT

Implementations SHOULD NOT use a packet reordering threshold (kPacketThreshold) less than 3, which is the RECOMMENDED initial value based on TCP loss detection best practices. Adaptive algorithms like RACK that increase the threshold after spurious losses are expected to be at least as useful in QUIC as in TCP.

quic, congestion

normative-requirement §7.3.3 MUST

In congestion avoidance, the increase to the congestion window MUST be limited to at most one maximum datagram size per congestion window acknowledged, implementing additive increase.

quic, congestion

normative-requirement §5.2 MUST

min_rtt MUST be set to latest_rtt on the first RTT sample and to min(min_rtt, latest_rtt) on all subsequent samples. Endpoints SHOULD reset min_rtt to the newest RTT sample after persistent congestion is established to avoid repeatedly declaring persistent congestion when the RTT increases.

quic, congestion

normative-requirement §7.3.2 MUST

On entering a recovery period, a sender MUST set ssthresh to half the congestion window at loss detection, and the congestion window MUST be set to the reduced ssthresh value before exiting recovery. A single packet MAY be sent immediately upon entering recovery to speed up loss recovery.

quic, congestion

normative-requirement §7.5 MUST NOT

Probe packets MUST NOT be blocked by the congestion controller, but a sender MUST count them as additionally in flight since they add network load. Senders MUST either use pacing or limit bursts; SHOULD limit bursts to the initial congestion window.

quic, congestion

normative-requirement §7.8 SHOULD NOT

The congestion window SHOULD NOT be increased during slow start or congestion avoidance when bytes_in_flight is smaller than the congestion window and sending is not pacing-limited, to avoid inflating the window during underutilization caused by application or flow control limits.

quic, congestion

normative-requirement §6.1.2 MUST

The time threshold for loss detection MUST be at least kGranularity (recommended 1 ms), computed as max(kTimeThreshold * max(smoothed_rtt, latest_rtt), kGranularity) with recommended kTimeThreshold of 9/8. Using max(smoothed_rtt, latest_rtt) protects against both lower and higher-than-expected latest RTT samples.

quic, congestion

normative-requirement §6.2.4 MUST

When a PTO timer expires, a sender MUST send at least one ack-eliciting packet as a probe. All probe packets sent on a PTO MUST be ack-eliciting. The sender MAY send up to two full-sized datagrams to reduce the probability of consecutive PTO events from a single lost datagram.

quic, congestion

normative-requirement §6.2.1 MUST

When a PTO timer expires, the PTO backoff MUST be increased by doubling the PTO period. The backoff is reset when an acknowledgment is received, except a client does not reset the PTO backoff on receiving Initial packet acknowledgments until the server completes address validation.

quic, congestion

normative-requirement §6.4 MUST

When Initial or Handshake packet protection keys are discarded, the sender MUST discard all recovery state for those packets and MUST remove them from bytes in flight. The PTO and loss detection timers MUST be reset because discarding keys signals forward progress.

quic, congestion

normative-requirement §7.6.2 MUST

When persistent congestion is declared — all packets sent between two lost ack-eliciting packets over a duration exceeding (smoothed_rtt + max(4*rttvar, kGranularity) + max_ack_delay) * kPersistentCongestionThreshold are unacknowledged — the congestion window MUST be reduced to kMinimumWindow (recommended 2 * max_datagram_size).

quic, congestion

protocol-element §5

RTT estimation tracks three values per path: min_rtt (minimum observed over a period, unadjusted for ACK delay), smoothed_rtt (exponentially weighted moving average), and rttvar (mean deviation). These are initialized from kInitialRtt (recommended 333 ms) and updated on each RTT sample drawn from ACK frames.

quic, congestion

protocol-element §5.3

smoothed_rtt and rttvar are updated as: smoothed_rtt = 7/8 * smoothed_rtt + 1/8 * adjusted_rtt; rttvar = 3/4 * rttvar + 1/4 * |smoothed_rtt - adjusted_rtt|. adjusted_rtt subtracts the peer-reported ACK delay bounded by max_ack_delay (only enforced after handshake confirmation) provided the result is not less than min_rtt.

quic, congestion

protocol-element §6.2.1

The PTO period is computed as: PTO = smoothed_rtt + max(4*rttvar, kGranularity) + max_ack_delay. For Initial and Handshake packet number spaces max_ack_delay is 0. When ack-eliciting packets in multiple spaces are in flight, the timer MUST be set to the earlier of the Initial and Handshake values.

quic, congestion

security-consideration §8.3

A receiver can misreport ECN-CE markings: suppressing them inflates the sender's rate potentially causing congestion, while reporting extra markings unnecessarily reduces it. Senders can detect suppression by occasionally marking packets ECN-CE and disabling ECN if those marks are not reflected in subsequent acknowledgments.

quic, security, congestion, ecn

security-consideration §8.1

Loss detection and congestion control consume signals — delay, loss, and ECN markings — from unauthenticated entities. An attacker can reduce endpoints' sending rates by dropping packets, strategically altering path delay, or changing ECN codepoints in transit.

quic, security, congestion

security-consideration §8.2

Packets carrying only ACK frames can be heuristically identified by their size, potentially revealing link characteristics or application behavior patterns. Endpoints can mitigate this by bundling acknowledgments with other frames or by using PADDING frames at a potential performance cost.

quic, security, privacy

state-machine §7.3

The NewReno congestion controller defines three states: Slow Start (window below ssthresh, grows by bytes acknowledged per ACK); Recovery (entered on loss or ECN-CE increase, window reduced to half then held until a packet sent during recovery is acknowledged); Congestion Avoidance (window at or above ssthresh outside recovery, AIMD growth). Persistent congestion or a new path resets to Slow Start.

quic, congestion