v153 · network · webtransport

WebTransport send groups and stream prioritization

Outgoing WebTransport streams grow a scheduling vocabulary: transport.createSendGroup() mints a WebTransportSendGroup to organise related streams, every outgoing stream becomes a WebTransportSendStream with mutable sendGroup and sendOrder attributes, and both streams and groups answer getStats() with { bytesWritten, bytesSent, bytesAcknowledged } — all while send streams stay transferable to workers.

concepts

  1. Three interfaces, one contract

    Interrogate the real objects: createSendGroup on the transport prototype, WebTransportSendStream as a WritableStream subclass with exactly the members the spec names, WebTransportSendGroup with its lone getStats(), and the illegal-constructor rules that make instances session-only.

  2. The workbench: groups and stream options, called for real

    Call createSendGroup() on a connecting transport, await the group's real getStats(), open a createUnidirectionalStream({ sendGroup, sendOrder }) attempt, and watch which dictionary members this build actually converts — every outcome real, including the failures.

  3. The scheduler, made visible

    The explainer's use cases — one stream per video frame, bandwidth split between a media group and a sync group — run in a labelled local model that implements the spec's strict-ordering sentence, after a real probe reports whether this build could do it natively.

why it shipped

Applications multiplex everything over one connection: frames of video, game state, file transfers, chat. Plain WritableStreams gave them no way to say which bytes matter more, so a burst of bulk traffic could starve the frame that should have painted next. sendOrder gives queued bytes a rank — among strictly-ordered streams, higher sendOrder drains first, FIFO within each stream — and WebTransportSendGroup scopes that ranking so one subsystem's priorities don't fight another's. Per-stream and per-group getStats() close the loop: bytesAcknowledged versus bytesWritten tells you whether the scheduling is actually landing. The W3C WebTransport WG reached consensus on the design at TPAC 2025; WebKit ships it in Safari 26.4, Firefox has sendOrder with groups in progress.

the API

const media = transport.createSendGroup();
const frame = await transport.createUnidirectionalStream({
  sendGroup: media,
  sendOrder: frameNumber,        // newer frames outrank older ones
});
frame.sendOrder = frameNumber + 1000;   // mutable: promote mid-flight

const { bytesWritten, bytesSent, bytesAcknowledged } = await frame.getStats();
const groupTotals = await media.getStats();   // the same counters, aggregated

references