§3.1
Chapter 03 · Reliability, Loss Recovery, and Congestion Control Mechanics

§3.1Packet Numbering, Acknowledgments, and Loss Detection

RFC 9002RFC 9000

Learning objective. Explain how QUIC acknowledges packets, how a sender turns those acknowledgments into an RTT estimate, and how it decides a packet is lost: the three mechanisms every later recovery and congestion decision is built on.

Acknowledging by range, without ambiguity #

Recall that packet numbers are monotonic within each number space and never reused, so an acknowledgment names exactly one transmission (§1.2). QUIC's ACK frame (0x02, or 0x03 when it carries ECN counts) reports the packets a receiver has seen as ranges. It is always selective, like TCP SACK but built in rather than optional. And QUIC acknowledgments are irrevocable: once a packet is acknowledged it stays acknowledged, so a sender can free that state permanently, unlike TCP where a SACK can be reneged ([RFC 9000 §13.2]).

01byte offsetType0x020x03 adds ECN8 b · 1 BLargest Acknowledgedhighest PN ackedvarintACK Delayscaled µsvarintACK Range Count# Gap/Range pairsvarintFirst ACK Rangerun below LargestvarintACK Range …Gap + Length × count0..*ECN CountsECT0·ECT1·CE · 0x030..*
Fixed-width fieldLength / count prefixVariable-length valueAEAD-protected / encrypted
Fig. 3.1-1ACK frame — RFC 9000 §19.3RFC 9000 §19.3

The frame starts from the Largest Acknowledged packet number and walks downward: the First ACK Range says how many packets below Largest are contiguously acknowledged, and each subsequent pair is a Gap (unacknowledged packets to skip) followed by an ACK Range Length (acknowledged packets). The ACK Delay field reports how long the receiver waited before sending the acknowledgment, encoded in microseconds scaled by the peer's ack_delay_exponent (constants.md §6). The sender needs it to compute RTT correctly.

From an ACK to an RTT estimate #

When an ACK newly acknowledges the largest packet number, the sender takes an RTT sample: latest_rtt = ack_time − send_time_of_largest_acked ([RFC 9002 §5.1]). It then subtracts the receiver's reported ACK Delay (when doing so keeps the sample at or above min_rtt) to get adjusted_rtt, and folds that into two running estimates ([RFC 9002 §5.3]):

RTT update (RFC 9002 §5.3)TEXT
smoothed_rtt = 7/8 * smoothed_rtt + 1/8 * adjusted_rtt
rttvar       = 3/4 * rttvar       + 1/4 * abs(smoothed_rtt - adjusted_rtt)

smoothed_rtt is the exponentially weighted average RTT; rttvar tracks its variation. Together with min_rtt (the smallest RTT seen, unadjusted) they drive every timer in this chapter — most importantly the PTO of §3.2.

Deciding a packet is lost #

QUIC never assumes loss from a timer alone if it can avoid it; it prefers evidence. A packet is declared lost when it is unacknowledged, a later packet has been acknowledged, and either of two thresholds is crossed ([RFC 9002 §6.1]):

  • Packet threshold. The packet was sent at least kPacketThreshold (3) packets before the newly acknowledged largest. Reordering of up to three packets is tolerated before loss is inferred.
  • Time threshold. The packet was sent longer than loss_delay before the largest acknowledged packet was sent, where loss_delay = kTimeThreshold × max(latest_rtt, smoothed_rtt) with kTimeThreshold = 9/8, floored at kGranularity (1 ms) (constants.md §8).
ReceiverSendergot 5, 6, 8 — gap at7RTT sample frompkt 8 · packet 7 notyet loststill no 77 is 3 behind largestand past the timethreshold → lostpacket 5packet 6packet 7 (lost)packet 8ACK Largest=8, ranges cover 8,6,5packet 9ACK Largest=9, ranges cover9,8,6,5packet 10 (retransmits 7's frames)
Fig. 3.1-2A loss inferred from acknowledgments. Packet 7 is missing; once later packets are acknowledged and 7 is both three packets behind the largest and past the time threshold, it is declared lost and its frames are resent in a new packet.RFC 9002 §6.1

Because either condition suffices, a single dropped packet is usually detected within a round trip of the next acknowledgment. No timer required. The timer-based fallback, for the case where nothing is acknowledged, is the PTO.

Note

"Retransmission" in QUIC means resending the frames, not the packet. The lost packet's number is retired forever; its STREAM, CRYPTO, or other frames are bundled into a brand-new packet with a fresh number (§1.2). That is why loss detection can key entirely off packet numbers while delivery stays keyed off stream offsets.

In practice

editorial Acknowledgment frequency is a real tuning knob. A receiver that ACKs too rarely starves the sender's RTT samples and loss detection; one that ACKs every packet wastes uplink and CPU. The base spec favors acknowledging at least every second ack-eliciting packet and within max_ack_delay, but extensions like QUIC ACK Frequency let a sender ask the receiver to ACK less often on clean paths. Worth knowing when you see suspiciously sparse or dense ACK traffic in a capture (§11.2).

Takeaways #

Selective, irrevocable, range-based ACKs give QUIC a precise picture of what arrived; RTT samples (corrected for ACK Delay) feed smoothed_rtt and rttvar; and loss is inferred from acknowledgments via a packet or time threshold rather than guessed from a timer. With "what was lost" established, §3.2 turns to recovering it — retransmission and the probe timeout that covers the case where the ACKs themselves stop arriving.