§9.1
Chapter 09 · Real-Time Traffic Optimization for Low Latency and Jitter

§9.1Latency Sources in QUIC and HTTP3 Data Paths

RFC 9000RFC 9002

Learning objective. Enumerate the sources of latency and jitter in a QUIC/HTTP-3 data path after the handshake: pacing, ACK delay, loss recovery, and the one that dominates real-time traffic, in-order delivery holding already-arrived data. Naming them lets the rest of the chapter attack each.

Latency is not one number #

Chapter 8 budgeted the setup cost in round trips (§8.1). Real-time traffic (interactive audio and video, gaming, telemetry) lives in the steady state, where the connection is already open and the question is how long each individual message takes from send() on one side to recv() on the other, and how much that time varies. That variance is jitter, and for interactive media it hurts as much as raw latency: a jittery stream must buffer to stay smooth, and the buffer is added latency.

The per-message delay is a sum of distinct sources, each with its own fix:

App (receiver)QUIC receiverQUIC senderApp (sender)1. pacing /congestion windowmay hold the send2. chunk C arrived,but in-order deliveryHOLDS it4. loss detected →retransmit chunk B(≈1 RTT later)jitter = variance across these per-packet delaysmedia frame → several STREAMchunkspacket 1 (chunk A)packet 2 (chunk B) — LOSTpacket 3 (chunk C)ACK 1,3 (gap at 2) — 3. afterack-delaypacket 4 (retransmit chunk B)now deliver B, then C —head-of-line delay = the wholerecovery
Fig. 9.1-1The latency sources on a steady-state data path. A send can be held by pacing or the congestion window (1); a lost packet makes the receiver's in-order delivery HOLD later chunks that already arrived (2); the ACK is delayed up to max_ack_delay (3); and recovery costs about a round trip before the retransmit arrives (4). The head-of-line delay — later data waiting on a retransmit — is the one that dominates real-time traffic.RFC 9002 §5.3, §6.2; RFC 9000 §13.2.1

The four sources, and which ones bite #

1. Send-side holding: pacing and the congestion window. A packet is not sent the instant the application hands it over. It may wait for the congestion controller to allow it, or be spread out by pacing, deliberately spacing packets to avoid bursts ([RFC 9002 §7.7]). On a congestion- or flow-control-limited connection this hold can be significant; for a real-time flow it is a reason to keep the send rate under the available window rather than bursting.

2. In-order delivery holding arrived data: the real-time killer. QUIC removed inter-stream head-of-line blocking: a loss on stream 4 no longer stalls stream 8 (§4.4). But within a single stream, delivery is still reliable and ordered. So if packet 2 is lost, the receiver holds packets 3 and 4 (which have already arrived) until the retransmit of 2 shows up, because the application must see the bytes in order. For a bulk download that hold is invisible; for a live video stream it is a visible stall, and it is why real-time media often should not use a reliable ordered stream at all (§9.3).

3. ACK delay. A receiver may hold its acknowledgment briefly to batch it, up to the max_ack_delay it advertised (default 25 ms, [RFC 9000 §18.2]). This is efficient for throughput but adds to how quickly the sender learns of loss and recovers. The sender removes the reported delay from its RTT estimate (§8.2), but the wall-clock delay before recovery is real.

4. Loss recovery. When a packet is lost, recovering it costs about a round trip: the sender must detect the loss (by packet or time threshold, or a PTO) and retransmit, and the data arrives an RTT later (§8.2). For a reliable stream this round trip is added directly to the delivery time of everything held behind the loss — source 4 is what makes source 2 expensive.

Jitter: the variance across all of these #

Each source varies from packet to packet: pacing gaps differ, some packets are lost and some are not, ACK delay fluctuates, RTT itself wobbles with queueing. Jitter is the variance of the total. An application that needs smooth playout must absorb that variance in a de-jitter buffer, holding data for the worst expected delay so the stream plays out evenly. This means the buffer size, and thus the effective latency, is set by the tail of the delay distribution, not its average. Cutting jitter therefore cuts latency twice: directly, and by letting the playout buffer shrink.

Worked example: one lost packet in a live stream #

Trace Figure 9.1-1. The application hands three media chunks to QUIC; pacing may already have spread their sends (source 1). Chunk B's packet is lost, but chunk C arrives — and the receiver's transport holds C, because in-order delivery must give the application B before C (source 2). The receiver's ACK, reporting the gap, comes after up to max_ack_delay (source 3). The sender detects the loss and retransmits B, which arrives about a round trip later (source 4); only then can the receiver deliver B and the held C. For a file that is fine. For a live stream, chunk C (fully received) was stuck waiting on a retransmit of data that, for real-time purposes, was already too late to matter. That is the core tension the rest of the chapter resolves.

Note

The sources compound in a specific order for real-time: reliability (source 2) turns a single loss into a multi-packet stall, and loss recovery (source 4) sets how long that stall lasts. This is why the biggest real-time win is not making recovery faster but making it unnecessary — delivering data that does not have to wait in order, via unreliable DATAGRAM frames (§9.3). You cannot pace or ACK-tune your way out of a head-of-line stall; you can only avoid incurring it.

In practice

editorial When a real-time stream feels laggy or stuttery, profile the sources separately before tuning. A steady delay with low variance points at pacing or the congestion window (source 1). Check whether you are sending above the available rate. Periodic spikes aligned with packet loss point at head-of-line blocking plus recovery (sources 2 and 4). The fix is a transport choice (unreliable datagrams), not a knob. A delay that tracks max_ack_delay points at ACK batching (source 3). Chasing the wrong source (shrinking a playout buffer to fix a head-of-line stall, say) makes the experience worse.

Takeaways #

Steady-state latency is a sum of send-side holding (pacing/congestion window), in-order delivery holding already-arrived data behind a loss, ACK delay, and the round trip of loss recovery. Jitter is the variance across all of them, paid again in the playout buffer it forces. For real-time traffic the dominant source is in-order delivery turning one loss into a stall, which no amount of tuning removes. The chapter attacks each source in turn: packetization and MTU (§9.2), recovery trade-offs and unreliable delivery (§9.3), backpressure (§9.4), and a tuned media profile (§9.5).