Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider adding finalResponseHeaders{Start|End} times #345

Open
noamr opened this issue Aug 31, 2022 · 30 comments
Open

Consider adding finalResponseHeaders{Start|End} times #345

noamr opened this issue Aug 31, 2022 · 30 comments
Assignees

Comments

@noamr
Copy link
Contributor

noamr commented Aug 31, 2022

Since we've added early hints, now TTFB in RUM, which maps to responseStart means something slightly different than it did before (though technically it represents the same thing).

For services that rely on final response timing, perhaps we should also expose when the final headers started arriving, and when they ended and the body started?

@LPardue
Copy link
Contributor

LPardue commented Aug 31, 2022

What is the definition of final that we're using here?

From the HTTP RFC, a server can respond to a single request with multiple interim responses (1xx) and a single final response messages (2xx through 5xx)
; see https://www.rfc-editor.org/rfc/rfc9110.html#section-15.2-3

A client MUST be able to parse one or more 1xx responses received prior to a final response, even if the client does not expect one. A user agent MAY ignore unexpected 1xx responses.

And do we care about measuring the arrival times of trailer field sections on the final response message?

@noamr
Copy link
Contributor Author

noamr commented Aug 31, 2022

What is the definition of final that we're using here?

From the HTTP RFC, a server can respond to a single request with multiple interim responses (1xx) and a single final response messages (2xx through 5xx) ; see https://www.rfc-editor.org/rfc/rfc9110.html#section-15.2-3

This definition of final :)
The last response, which is the first response that's not a 1xx or a 3xx

And do we care about measuring the arrival times of trailer field sections on the final response message?

Perhaps this is a separate conversation, since trailers are not currently widely supported.

@LPardue
Copy link
Contributor

LPardue commented Aug 31, 2022

This definition of final :)
The last response, which is the first response that's not a 1xx or a 3xx

Great! I support add such timing markers.

Perhaps this is a separate conversation, since trailers are not currently widely supported.

Happy for that to be spun off

@colinbendell
Copy link

We should also consider also finalResponseBodyStart time to distinguish header-end and the data payload start

@nicjansma
Copy link
Contributor

Some points from the 9/1 W3C WebPerf call:

  • Could also be useful to know the timing difference between finalResponseHeadersEnd and another new field like finalResponseBodyStart, AKA if headers are flushed early, when does the response body content begin? This could help with both Early Hint and regular transfer cases.
  • Should be TAO protected, like responseStart
  • One question to resolve: Clarify how PerformanceTiming.responseStart relates to Early Hint responses navigation-timing#181
  • Noam is looking for any additional feedback or concerns

@tunetheweb
Copy link
Member

tunetheweb commented Sep 1, 2022

To @colinbendell 's point in #181, instead of adding finalXXX timings, we could add the following:

  • interimResponseStart (between secureConnectionStart and responseStart) and change responseStart to mean final response start, as many may have assumed it has until now.

And then also add:

  • responseHeadersEnd (just after responseStart)
  • responseBodyStart (just before responseEnd)

Only thing I don't like about that is we don't have the equivalent opposites (e.g. responseHeadersStart which is basically responseStart) and responseBodyEnd (which is basically responseEnd if you ignore the the little used HTTP Trailers) so might be confusing.

@noamr
Copy link
Contributor Author

noamr commented Sep 1, 2022

We don't always need equivalent opposites, like with secureConnectionStart. I think that's OK

@tunetheweb
Copy link
Member

We don't always need equivalent opposites, like with secureConnectionStart. I think that's OK

Yeah I know, but there we don't have secureConnectionEnd at all (though nothing to stop it being added in future), but here we DO have responseHeadersStart - we just call it something else (responseStart).

Anyway, I'll get over it. Just looks a little odd.

@colinbendell
Copy link

I agree with @tunetheweb's proposal. This focuses responseStart and responseEnd to target the whole response of the "final" response code and also preserves legacy interpretations. The added metrics optionally increase the resolution for newer rum providers without burdening these vendors to release patches.

@LPardue
Copy link
Contributor

LPardue commented Sep 1, 2022

Please don't prefix anything with early. If we want to support interim HTTP responses, call it that. Expect the HTTP to define more 1xx codes, because its been a part of HTTP since forever.

If we only want to record the time of the first interim response, that fine. But let's be clear. What these events measure. Maybe today first and last interim response are measured at the same time due to fetch. In the future, if fetch changes to support multiple interim responses, our first and last markers would be ready.

@tunetheweb
Copy link
Member

We don't always need equivalent opposites, like with secureConnectionStart. I think that's OK

Yeah I know, but there we don't have secureConnectionEnd at all (though nothing to stop it being added in future), but here we DO have responseHeadersStart - we just call it something else (responseStart).

Anyway, I'll get over it. Just looks a little odd.

Though guess you could in theory have a responseBodyEnd before responseEnd (e.g. if considering Trailers), and we're just choosing not to include that now as little need for it as responseEnd is sufficient, in the same way as we're not including secureConnectionEnd. And similarly, theoretically responseHeadersStart could be after responseStart, but again we just won't include it now as little need of it.

@tunetheweb
Copy link
Member

Please don't prefix anything with early. If we want to support interim HTTP responses, call it that. Expect the HTTP to define more 1xx codes, because its been a part of HTTP since forever.

If we only want to record the time of the first interim response, that fine. But let's be clear. What these events measure. Maybe today first and last interim response are measured at the same time due to fetch. In the future, if fetch changes to support multiple interim responses, our first and last markers would be ready.

Updated my comment to interimResponseStart instead.

@noamr
Copy link
Contributor Author

noamr commented Sep 1, 2022

Please don't prefix anything with early. If we want to support interim HTTP responses, call it that. Expect the HTTP to define more 1xx codes, because its been a part of HTTP since forever.

HTTP 103 is defined as "Early Hints", that's where early comes from.
1xx is interim in HTTP lingo, but 103 is early in HTML/fetch/browser lingo.
I don't think we want to start measuring other interim responses.

Perhaps earlyHintsStart ?

@tunetheweb
Copy link
Member

Perhaps earlyHintsStart ?

I'm against being that specific. Who knows what the future will bring.

@noamr
Copy link
Contributor Author

noamr commented Sep 1, 2022

Perhaps earlyHintsStart ?

I'm against being that specific. Who knows what the future will bring.

Perhaps when we have new features in the future we find new names for their metrics and be specific about them?
If what this feature does currently is early hints, and it's defined in HTTP, perhaps we should be specific?

@colinbendell
Copy link

The HTTP spec calls these "Informational" responses (1xx). Should we converge on this language?

@tunetheweb
Copy link
Member

Perhaps when we have new features in the future we find new names for their metrics and be specific about them?
If what this feature does currently is early hints, and it's defined in HTTP, perhaps we should be specific?

Possibly. Do we measure WebSockets this way? Should interimResponseStart measure when that 101 response comes in, and before the first bytes sent on the WebSocket?

Similarly HTTP/2 also had the upgrade option with 101 before the "final response" was sent, but that was removed from the latest version.

The HTTP spec calls these "Informational" responses (1xx). Should we converge on this language?

I like this.

@LPardue
Copy link
Contributor

LPardue commented Sep 1, 2022

Only h2c, as defined in RFC 7540, uses 101. The latest revision of HTTP/2 is RFC 9113, which as Barry points out no longer mentions this feature. In most part because browsers do not implement h2c. We should ignore this.

However 101 for WebSocket upgrade over HTTP/1.1 is an actual thing, we should not ignore it and consider if WebSockets and timings are anything we care about here.

103 Early Hints is defined and is seeing use. And there are use cases for other status codes. For example, 104 is provisionally allocated for resumable upload - newly adopted in the IETF HTTP WG. That specific provisional allocation might fizzle out, but let's be open to supporting the well-defined HTTP extension point of the 1xx status ranges; if we fail to do that job, we damage its future potential.

I disagree with calling things informational responses. RFC 9110 doeant use that term, instead it defines interim responses, which use informational status codes. Terminology needs to be precise and consistent unless there is a good reason to diverge.

Case in point, HTTP as defined in RFC 9110 has moved away from the terms payload and body, and now consistently uses the term "content". Ideally, W3C would align. But I believe due to legacy, that such a change would be disruptive However, new things that we are discussing here have no such legacy.

@colinbendell
Copy link

I disagree with calling things informational responses. RFC 9110 doeant use that term, instead it defines interim responses, which use informational status codes. Terminology needs to be precise and consistent unless there is a good reason to diverge.

I'm not sure I follow. Section 15.2 of rfc9110 calls 1xx "informational" class of response codes.

@LPardue
Copy link
Contributor

LPardue commented Sep 1, 2022

Status codes are only a piece of a response message, the other pieces include metadata (in the form of field sections) and content. RFC 9110 does not use the term "informational response" anywhere. In contrast it uses the term "interim response" 4 times to describe a non-final response that includes a 1xx( informational) class of status code.

@dotjs
Copy link

dotjs commented Sep 1, 2022

I'm in favour of using interim as it expresses the non-final and non-authoritative nature of the response. As RFC 9110 states

A single request can have multiple associated responses: zero or more "interim" (non-final) responses with status codes in the "informational" ([1xx] range, followed by exactly one "final" response with a status code in one of the other ranges.

@noamr
Copy link
Contributor Author

noamr commented Sep 2, 2022

Only h2c, as defined in RFC 7540, uses 101. The latest revision of HTTP/2 is RFC 9113, which as Barry points out no longer mentions this feature. In most part because browsers do not implement h2c. We should ignore this.

However 101 for WebSocket upgrade over HTTP/1.1 is an actual thing, we should not ignore it and consider if WebSockets and timings are anything we care about here.

We currently don't record resource timing for WebSockets at all, but I can see the other points.

The main issue I have with interim/informational is that we might not have interim responses at all (most cases...), and also in some cases we'd have more than one, and this measures only the first one.

How about firstResponseStart (which could be interim or the final one) and responseStart?
Otherwise perhaps firstInterimResponseStart and have it be zero if there aren't any. (I don't like having too many zeroes in the resource timing sequence, so not sure it's a favorite)

noamr added a commit to noamr/fetch that referenced this issue Sep 2, 2022
See w3c/resource-timing#345

Since early hints have landed, there are additional useful timestamps
that are currently not exposed:

- First interim response start (e.g. when we received a 103)
  as a different timestamp from the final response start
  (e.g. when we received the 200)

- Final headers received (when the last header has been received and
  we're ready for the body)

- First bytes of the body received

The naming in whatwg#345 is not finalized yet, but it's clear that these
are the 3 interesting timestamps. This PR exposes those for later
use by resource timing.
@noamr
Copy link
Contributor Author

noamr commented Sep 2, 2022

I posted a PR for the fetch spec. It shouldn't affect the naming bike shed, we can choose the names in the subsequent resource timing PR.

@annevk
Copy link
Member

annevk commented Sep 26, 2022

One thing that I'm missing from this thread is a discussion of use cases.

@noamr
Copy link
Contributor Author

noamr commented Sep 27, 2022

One thing that I'm missing from this thread is a discussion of use cases.

It's been discussed in the WebPerfWG call.

The main use case is that servers who serve early hints and might have latency before serving the final headers/body now don't have visibility as to where this latency lies.

@colinbendell
Copy link

There are a few use cases behind the above discussion:

  1. responseStart is previously understood by the industry as 'time-to-first-byte'. Many libraries and rum products in the industry operate with this exception. The strict definition of responseStart breaks the colloquial understanding in the ecosystem.
  2. for use cases where early hints are available, the presence of firstInterimResponseStart will help rum providers and analytics effectively cohort results. This is a current challenge since there is no way to know if the results from clients is an experience where early hints was sent, where early hints were sent and there was >0ms before the http headers arrived or where early hints were not sent.
  3. many frameworks are increasingly returning to http streaming to emit http headers early while the backend continues to process and compose the body. Having responseBodyStart will help segment and cohort experiences in the same way that use case {2} identifies.

noamr added a commit to noamr/fetch that referenced this issue Nov 28, 2022
See w3c/resource-timing#345

Since early hints have landed, there are additional useful timestamps
that are currently not exposed:

- First interim response start (e.g. when we received a 103)
  as a different timestamp from the final response start
  (e.g. when we received the 200)

- Final headers received (when the last header has been received and
  we're ready for the body)

- First bytes of the body received

The naming in whatwg#345 is not finalized yet, but it's clear that these
are the 3 interesting timestamps. This PR exposes those for later
use by resource timing.
noamr added a commit that referenced this issue Dec 18, 2022
Add 3 response times:
- firstInterimResponseStart: the first 103
- responseHeadersEnd: All headers have been received
- responseBodyStart: The body started streaming

Closes #345
Depends on whatwg/fetch#1483
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 16, 2023
This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345
Bug: 1402089
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 16, 2023
This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 16, 2023
This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 16, 2023
This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 17, 2023
This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 18, 2023
This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 19, 2023
This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
aarongable pushed a commit to chromium/chromium that referenced this issue Jan 19, 2023
This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4165825
Reviewed-by: Bence Béky <bnc@chromium.org>
Commit-Queue: Noam Rosenthal <nrosenthal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1094571}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 19, 2023
This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4165825
Reviewed-by: Bence Béky <bnc@chromium.org>
Commit-Queue: Noam Rosenthal <nrosenthal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1094571}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 19, 2023
This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4165825
Reviewed-by: Bence Béky <bnc@chromium.org>
Commit-Queue: Noam Rosenthal <nrosenthal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1094571}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Feb 1, 2023
…onseStart, a=testonly

Automatic update from web-platform-tests
Resource Timing: Expose firstInterimResponseStart

This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4165825
Reviewed-by: Bence Béky <bnc@chromium.org>
Commit-Queue: Noam Rosenthal <nrosenthal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1094571}

--

wpt-commits: e75f154bb894b0e2bf78cf1ac04e1cbecedebdc6
wpt-pr: 37984
jamienicol pushed a commit to jamienicol/gecko that referenced this issue Feb 3, 2023
…onseStart, a=testonly

Automatic update from web-platform-tests
Resource Timing: Expose firstInterimResponseStart

This adds an entry to PerformanceResourceTiming:
- firstInterimResponseStart: the time of the first early-hints header

It also changes the meaning of responseStart to be the first
non-informational header (non-103).

Implemented for Quic, Spdy and HTTP.

All behind a feature runtime flag (ResourceTimingInterimResponseTimes)

Spec issue: w3c/resource-timing#345

Bug: 1402089
Change-Id: I2f050788515959e3576f3cf2bd8df13ff848090a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4165825
Reviewed-by: Bence Béky <bnc@chromium.org>
Commit-Queue: Noam Rosenthal <nrosenthal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1094571}

--

wpt-commits: e75f154bb894b0e2bf78cf1ac04e1cbecedebdc6
wpt-pr: 37984
@LPardue
Copy link
Contributor

LPardue commented Feb 16, 2023

Something that might be worth noting (if not already covered) is that in some scenarios, the checkpoints could appear to have the same values at the client, even if sent and different times on the server. This is especially noticeable if the client has large TCP receive windows and reads a "batch" of data after letting it accumulate for a little while.

@noamr
Copy link
Contributor Author

noamr commented Apr 24, 2023

This is now implemented in chrome behind a flag (ResourceTimingInterimResponseTimes):

  • firstInterimResponseStart is the time when the 103 response arrives
  • responseStart is the time when the final response arrives

It applies to resource timing, but probably only useful for navigation timing entries.
I would like to enable this by default soon.

noamr added a commit to noamr/fetch that referenced this issue May 4, 2023
See w3c/resource-timing#345

Since early hints have landed, there are additional useful timestamps
that are currently not exposed:

- First interim response start (e.g. when we received a 103)
  as a different timestamp from the final response start
  (e.g. when we received the 200)

- Final headers received (when the last header has been received and
  we're ready for the body)

- First bytes of the body received

The naming in whatwg#345 is not finalized yet, but it's clear that these
are the 3 interesting timestamps. This PR exposes those for later
use by resource timing.
noamr added a commit that referenced this issue May 4, 2023
Add 3 response times:
- firstInterimResponseStart: the first 103
- responseHeadersEnd: All headers have been received
- responseBodyStart: The body started streaming

Closes #345
Depends on whatwg/fetch#1483
annevk pushed a commit to whatwg/fetch that referenced this issue May 8, 2023
@noamr noamr closed this as completed in 55724b9 May 9, 2023
@annevk
Copy link
Member

annevk commented May 9, 2023

@noamr is there a follow-up bug for the other two timing channels or should this be reopened?

@noamr
Copy link
Contributor Author

noamr commented May 9, 2023

@noamr is there a follow-up bug for the other two timing channels or should this be reopened?

Oh this shouldn't have been closed, I changed from "Closes" to "Bug".

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

No branches or pull requests

7 participants