Skip to content

WebTransportReceiveStreamStats: define where bytes are "received" so bytesRead <= bytesReceived can be guaranteed #804

Open

Description

@jesup

WebTransportReceiveStreamStats.bytesRead "is always less than or equal to bytesReceived", and bytesReceived counts bytes "received so far", sequential up to the first missing byte. The spec doesn't say at which point in the implementation a byte counts as received.

That matters for multi-process implementations. In Firefox, QUIC runs in the network process and the stream's data is forwarded to the content process, where the application reads it. bytesRead is counted in the content process as the application pulls bytes. bytesReceived is reported by the network process. The network process's count can lag bytes it has already forwarded, so a stats snapshot can show bytesRead > bytesReceived. The invariant can't be kept without clamping bytesRead to bytesReceived, which is what we do now.

We should define "received" for this attribute. Two options:

  1. Received means delivered to the stream's readable (the point where bytes become available to read()), so bytesRead <= bytesReceived holds by construction.
  2. Keep "received by the transport", and relax the invariant, or say that user agents must not report bytesRead above bytesReceived.

I prefer option 1, because it also matches what an application can observe.

Activity

  1. jan-ivar commented on Oct 13, 2026

    @jan-ivar
    Member

    I believe the intent was 1: that these are stream access counters, not connection stats, with the (testable) invariant that there are (bytesReceived - bytesRead) bytes available to be read.

    Surfacing a category of "received" bytes that can't yet be read, would break this invariant. Worse, the IPC to produce the measurement would race with the IPC to produce the bytes.

    I suggest we clarify it's 1 with s/received/received and available to be read/

    Keep "received by the transport"

    I don't think the spec says that here. The same-named connection stat is close: it specifically reports "bytes received on the underlying connection", but that is not here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Discuss at next meetingFlags an issue to be discussed at the next WG working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions