v158 · webtransport · receive streams
bytesReceived vs bytesRead
Two counters, one diagnosis. bytesReceived is how much contiguous stream data the browser has taken off the network; bytesRead is how much your JavaScript has actually consumed. When the first races ahead of the second, the network is fine — your consumer is the bottleneck, and the gap is sitting in browser memory.
The real counters come from getStats() on a live session's receive stream, which needs an HTTP/3 endpoint this showcase cannot reach — and this build's support is probed for real below. The rig underneath is therefore a clearly-labelled local stand-in: a genuine ReadableStream with a producer and consumer you control, where the two counters are maintained by the page at the exact points the spec defines them. The streams machinery is real; only the network is replaced.
First, the real surface on this build
local model — plain ReadableStream, no network
Watch the gap grow and drain
bytesReceived (analogue)0 KB
bytesRead (analogue)0 KB
the gap = buffered in the browser0 KB
code path — what you would write against the real API
async function watchBackpressure(stream /* WebTransportReceiveStream */) {
const { bytesReceived, bytesRead } = await stream.getStats();
const buffered = bytesReceived - bytesRead; // bytesRead ≤ bytesReceived, always
if (buffered > HIGH_WATER) {
// the network is NOT the problem — our consumer is behind;
// shed work, skip frames, or move parsing off the main thread
}
}
// Firefox note: getStats() exists but currently rejects with
// NotSupportedError — await it in a try/catch, not bare.