Learning objective. Choose the right delivery model for a workload: reliable ordered streams versus unreliable DATAGRAM frames, understanding that for interactive media a retransmit that arrives after the playout deadline is worse than no retransmit at all.
Two delivery models, one connection #
QUIC gives an application two ways to send data over the same connection, sharing one handshake, one congestion controller, one encryption context ([RFC 9221 §2]):
- Reliable, ordered STREAM frames. Every byte is retransmitted until acknowledged and delivered in order. This is the right model when all the data must arrive and order matters: a file, a control message, an HTTP response.
- Unreliable, unordered DATAGRAM frames. Never retransmitted on loss, never reordered into sequence: the model for data whose value expires, where a late byte is useless ([RFC 9221 §1]).
The choice turns on a single question: is late data still useful?
Why "late is useless" changes everything #
For a file download, a retransmit that arrives a round trip late is perfect — the byte was needed and now it is here. For a live video call, the frame that a retransmit repairs was due on screen already; by the time it arrives, the player has moved on. Worse, on a reliable stream that late frame also held everything behind it (the in-order rule of §9.1), so one loss stalled the whole stream to deliver data nobody can use. Reliable delivery optimizes for completeness; interactive media needs timeliness, and the two conflict exactly when the network drops a packet.
Unreliable datagrams resolve the conflict by not trying. When frame 21 is lost (Figure 9.3-1, bottom), frame 22 is delivered the instant it arrives — no head-of-line hold — and the sender, rather than resending stale data, sends fresh data: the next frame, a concealment cue, or a new keyframe. The connection spends its next transmission on what is useful now, not on repairing what is already too late.
What DATAGRAM frames do and don't do #
The DATAGRAM extension ([RFC 9221]) is precise about its guarantees, and each one matters for real-time design:
- Not retransmitted, but acknowledged. DATAGRAM frames "are not retransmitted upon loss detection," yet they "are ack-eliciting" ([RFC 9221 §5.2]). So the transport tells the sender whether each datagram was delivered or lost, but takes no action itself. The application decides: conceal, apply forward error correction, request a keyframe, or ignore it.
- The ack means transport-received, not app-processed. An acknowledgment "only indicates that the transport-layer handling on the receiver processed the frame and does not guarantee that the application on the receiver successfully processed the data" ([RFC 9221 §5.2]). It cannot replace an application-level acknowledgment.
- Congestion controlled, not flow controlled. Datagrams "employ the QUIC connection's congestion controller" ([RFC 9221 §5.4]), so a real-time flow still respects congestion signals and cannot flood the path. But they "do not contribute to any per-flow or connection-wide data limit" ([RFC 9221 §5.3]). There is no MAX_DATA credit and no receive-window backpressure (§9.4).
- Drop, don't queue, under congestion. When the congestion controller won't allow a datagram, the sender "MUST either delay sending the frame... or drop the frame without sending it" ([RFC 9221 §5.4]), and may honour an application-set expiration time. For real-time, dropping a stale frame is usually right: queuing it just delays the fresh frame behind it.
- No fragmentation, no ordering. A datagram must fit one packet (§9.2) and carries no QUIC-level sequence number: "DATAGRAM frames... are not associated with any stream ID" ([RFC 9221 §5.1]); any sequencing or multiplexing is the application's to define.
The frame itself is as small as its guarantees are thin: compare it with the STREAM frame's stream ID, offset, and FIN machinery (§4.1):
Matching model to workload #
| Workload | Late data useful? | Model | Why |
|---|---|---|---|
| File / API response | yes | reliable stream | completeness matters, no deadline |
| Video-on-demand (buffered) | yes (buffer absorbs) | reliable stream + buffer | a few seconds of buffer hide retransmits |
| Live conferencing / gaming | no | unreliable datagram | past the deadline, a repair is wasted |
| Media control / signaling | yes | reliable stream | must arrive, but low volume |
The nuance is streaming vs. interactive. Buffered streaming (video-on-demand, live with a multi-second delay) tolerates reliable delivery because its playout buffer is deep enough to absorb a retransmit's round trip. The completeness of a reliable stream is a feature, not a cost. Interactive media (conferencing, cloud gaming, real-time control) runs with a buffer of tens of milliseconds; a retransmit cannot arrive in time, so datagrams are the fit. Many real applications use both at once on one connection: datagrams for the media, a reliable stream for signaling and control.
Worked example: a video call frame #
Trace both halves of Figure 9.3-1 for a conferencing app. On a reliable stream, losing frame 11 holds frame 12 and repairs 11 a round trip later, but the call's 50 ms jitter buffer expired long ago, so the "correct" delivery is a glitch: a freeze while the stream stalled, then a jump. With datagrams, frame 22 plays on time; the sender learns 21 was lost and, instead of resending a now-useless frame, encodes the difference into frame 23 or sends a fresh keyframe. The viewer sees a momentary artifact rather than a freeze — the trade real-time media almost always wants.
Unreliable does not mean unmanaged. Because DATAGRAM frames are ack-eliciting, the application gets a loss/delivery signal per datagram and can build partial reliability on top: selectively retransmit only data still inside its deadline, add forward error correction so isolated losses need no round trip at all, or adapt the encoder's bitrate to the observed loss. QUIC supplies the timing signal and the congestion control; the application supplies the recovery policy suited to its notion of "too late."
editorial Pick the model per data type, not per connection. Media samples that expire → datagrams; signaling, keyframe requests, and stats that must arrive → a reliable stream on the same connection. Do not reach for datagrams to make a file transfer faster: without reliability you have re-created UDP and must rebuild everything QUIC streams gave you. And when you do use datagrams, act on the loss signal: a real-time app that sends datagrams but ignores the per-datagram ack/loss notifications is flying blind, unable to conceal, apply FEC, or back off its bitrate.
Takeaways #
Reliable streams optimize completeness; unreliable DATAGRAM frames optimize timeliness, and the choice is decided by whether late data is still useful. Datagrams are never retransmitted but are ack-eliciting and congestion-controlled (not flow-controlled), so the transport reports loss while the application owns recovery: concealment, FEC, or fresh data instead of stale repairs. Buffered streaming can use reliable delivery; interactive media needs datagrams, often alongside a reliable control stream. The flow-control and backpressure consequences of that "not flow-controlled" property are §9.4.