Skip to content

Conversation

@jan-ivar
Copy link
Member

@jan-ivar jan-ivar commented Sep 9, 2025

Fixes #674.


Preview | Diff

@jan-ivar jan-ivar self-assigned this Sep 9, 2025
@jan-ivar
Copy link
Member Author

jan-ivar commented Sep 9, 2025

Meeting:

index.bs Outdated
Comment on lines 1737 to 1738
:: The number of payload bytes sent on the [=underlying connection=], including retransmissions.
Excludes [[!QUIC]] framing, UDP and any other outer framing.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This concept is a little fiddly and will require special accounting.

If you want to measure the number of bytes that the application was able to usefully send/deliver/whatever, then you need to deduct stream and datagram headers. That's special WT-specific accounting, and useful, but you need to be a little more precise about what "payload bytes" (or my preferred "application bytes").

All that said, I do think that the retransmissions thing is much, much harder to account for.

You can define "application bytes" right here:

Suggested change
:: The number of payload bytes sent on the [=underlying connection=], including retransmissions.
Excludes [[!QUIC]] framing, UDP and any other outer framing.
:: The number of application bytes sent on the [=underlying connection=].
<dfn>Application bytes</dfn> is counted as the sum of
the bytes sent on streams, excluding stream headers,
and the bytes sent in datagrams, excluding any session identifiers.
The count of application bytes <pick-one>does not | does</pick-one>
count any retransmissions of stream data.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I prefer to avoid counting retransmissions. Accounting for retransmissions at this layer is much more intrusive on the implementation: a webtransport implementation is removed from the QUIC implementation that does retransmissions. You'd need very tight integration to do accurate accounting of retransmissions, because some stream bytes cannot be counted and only the webtransport code really knows which bytes those are. Given that this crosses multiple stack layers (WT > HTTP/3 > streams > retransmission) that's quite a burden.

I realize that this leads to a value that the application could measure for itself, mostly (datagram accounting isn't likely to work out perfectly with our API), but I think that the value is still very useful. The QUIC packet byte accounting is a better measure of the link performance.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the QUIC overhead constant across sent, retransmitted and acked?

Instead of going from 2 to 4 stats here, what if we counted the sum of stream headers sent on streams (in bytes) and session identifiers (in bytes) sent in datagrams? If we exposed that, either as a number or a ratio, apps could make due with 3 stats:

const applicationBytesSent = stats.bytesSent * (1 - stats.quicFrameOverheadRatio);
const applicationBytesAcked = stats.bytesAcknowledged * (1 - stats.quicFrameOverheadRatio);

?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the QUIC overhead constant

Not at all. Consider the case where you send data on a stream in a packet. You might have an entire packet dedicated to the stream data. There, your overhead is largely fixed. There is just a single byte, a connection ID (maybe empty), a packet number (1 to 4 bytes, the only variable part, which will depend on the current and expected in-flight data), the STREAM frame (offset and length), and AEAD tag. Maybe you have the stream type indicator if it is the start of a stream as well, which we wouldn't want to count either.

On the other hand, packets that squeeze in some stream data along with other maintenance frames look very different. Other stuff includes ACKs, flow control frames, stuff on other streams, and more. And the more you have to slice the stream data up, the higher the overhead.

So while there might be an average value over time, the overhead can vary greatly in practice. There is no simple formula.

@jan-ivar jan-ivar changed the title Add connection stats bytesAcknowledged & payloadBytes(Sent|Acknowledged) Add connection stats bytesAcknowledged & applicationBytes(Sent|Acknowledged) Sep 9, 2025
: <dfn for="WebTransportConnectionStats" dict-member>bytesSent</dfn>
:: The number of bytes sent on the [=underlying connection=], including retransmissions.
Does not include UDP or any other outer framing.
This counts the size of QUIC packets,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This counts the size of QUIC packets,
This includes the size of QUIC packets,

: <dfn for="WebTransportConnectionStats" dict-member>bytesAcknowledged</dfn>
:: The number of bytes acknowledged as received by the server using
QUIC's ACK mechanism on the [=underlying connection=].
This counts the size of QUIC packets,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This counts the size of QUIC packets,
This includes the size of QUIC packets,

@jan-ivar
Copy link
Member Author

jan-ivar commented Oct 7, 2025

Meeting:

  • Use case: how much can I shove down this pipe?
  • What is the cost in application bytes? (points to including retransmissions)
  • need to estimate throughput accurately (points to not including retransmissions)
  • potentially a lot of cross-layer work / additional scope
  • @vasilvv to check what we need for moq

Copy link
Member

@nidhijaju nidhijaju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we already covered this in a meeting and I missed it, but why do we need the two different versions of bytesSent/bytesAcked if we're consistent about how we measure it and estimatedSendRate? Are they both separately useful somehow?

: <dfn for="WebTransportConnectionStats" dict-member>bytesSent</dfn>
:: The number of bytes sent on the [=underlying connection=], including retransmissions.
Does not include UDP or any other outer framing.
This counts the size of QUIC packets,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of implies that WebTransport is running on QUIC. Can we find a way to describe the difference between QUIC and UDP framing that applies generally?

@jan-ivar
Copy link
Member Author

Overtaken by #702.

@jan-ivar jan-ivar closed this Nov 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

More stats

4 participants