§4.3
Chapter 04 · Stream Multiplexing and Flow Control for Performance

§4.3Stream Prioritization Patterns and Scheduling Strategies

RFC 9114RFC 9218

Learning objective. Explain how HTTP/3 signals relative importance between streams with the two-parameter RFC 9218 scheme, and how a server turns those signals into a send order that gets render-critical resources to the client first.

A deliberately simple scheme #

HTTP/2 shipped an elaborate priority tree of stream dependencies and weights; it proved hard to implement well and was deprecated. HTTP/3 does not carry it; the core spec defines no priority frames ([RFC 9114 §7.2]). Instead it adopts the Extensible Prioritization Scheme of RFC 9218, which reduces priority to two parameters carried in a Priority request header field (a structured field):

  • urgency (u). An integer 0–7, default 3, where smaller is more urgent. A server SHOULD transmit responses in urgency order. Level 7 is reserved for background work like software updates ([RFC 9218 §4.1]).
  • incremental (i). A boolean, default false, saying whether a partial response is useful. A progressively-rendered image is incremental; a script that must be complete to execute is not ([RFC 9218 §4.2]).

A client can also reprioritize an in-flight response with a PRIORITY_UPDATE frame (HTTP/3 types 0xF0700 for request streams, 0xF0701 for push, [RFC 9218 §7.2]), for example when the user scrolls an image into view.

The server does the scheduling #

Priority is a signal, not a command. Because all streams share one connection's send capacity, the server decides, moment to moment, which stream's data to put on the wire next, subject to flow control (§4.2) and congestion control (§3.3). RFC 9218 gives it a clear policy:

ServerClientschedule the sharedconnection byurgency, then byincrementalGET style.css · Priority u=2GET app.js · Priority u=2GET a.jpg · Priority u=4, iGET b.jpg · Priority u=4, istyle.css in full (u=2,non-incremental → sequential)app.js in full (u=2)a.jpg / b.jpg interleaved (u=4,incremental → round-robin)
Fig. 4.3-1Scheduling by the two parameters. Lower urgency values go first; within one urgency level, non-incremental responses are sent one-at-a-time to completion while incremental ones are round-robined so each makes progress.RFC 9218 §4, §10
  • Across urgency levels: serve lower u first. The style sheet and script at u=2 are sent before the images at u=4.
  • Within one urgency level, non-incremental: send each response to completion before starting the next. Interleaving two scripts would leave both unusable for longer; finishing one makes it usable sooner.
  • Within one urgency level, incremental: round-robin the responses so each makes progress. Two progressive images at the same urgency should both start rendering rather than one waiting for the other.

That combination is the whole art: urgency picks what matters, and the incremental flag picks sequential-vs-shared for things that matter equally.

Note

Prioritization only bites when streams compete: when the connection is send-limited by congestion or flow control. On an unloaded, high-capacity path everything goes out nearly at once and priority is moot. It earns its keep exactly when a page pulls dozens of resources through a constrained pipe, which is the common case on real networks (§4.5).

In practice

editorial Browsers already assign sensible defaults (render-blocking CSS and scripts at low urgency, images higher, prefetch at the bottom), so the most common mistake is a server that ignores the signals and serves first-come-first- served, undoing the browser's careful ordering. Verify your server actually implements RFC 9218 scheduling (many did not, early on). When debugging a slow first paint on HTTP/3, check the order in which the server put response bytes on the wire against the Priority values the client sent. A mismatch there delays render more than any amount of extra bandwidth fixes (§11.2).

Takeaways #

HTTP/3 replaces HTTP/2's priority tree with two signals — urgency (0–7) and incremental — that the client sends and the server acts on when streams compete for a shared connection: lowest urgency first, non-incremental sequentially, incremental round-robined. Getting this right is what turns QUIC's stream independence into fast rendering. §4.4 examines the flip side: how that stream independence removes the head-of-line blocking that made prioritization so fraught in TCP-based HTTP/2.