Copyright © 2022 W3C ® ( MIT , ERCIM , Keio , Beihang ). W3C liability , trademark and permissive document license rules apply.
This specification enables a server to communicate performance metrics about the request-response cycle to the user agent. It also standardizes a JavaScript interface to enable applications to collect, process, and act on these metrics to optimize application delivery.
This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.
This document was published by the Web Performance Working Group as an Editor's Draft.
Publication as an Editor's Draft does not imply endorsement by W3C and its Members.
This
is
merely
a
draft
document
and
may
be
updated,
replaced
or
obsoleted
by
other
documents
at
any
time.
It
is
inappropriate
to
cite
this
document
as
other
than
work
in
progress.
This
document
was
produced
by
a
group
operating
under
the
W3C
-internal
document.
It
has
no
official
standing
Patent
Policy
.
W3C
maintains
a
public
list
of
any
kind
and
does
not
represent
consensus
patent
disclosures
made
in
connection
with
the
deliverables
of
the
group;
that
page
also
includes
instructions
for
disclosing
a
patent.
An
individual
who
has
actual
knowledge
of
a
patent
which
the
individual
believes
contains
Essential
Claim(s)
must
disclose
the
information
in
accordance
with
section
6
of
the
W3C
Membership.
Patent
Policy
.
This document is governed by the 2 November 2021 W3C Process Document .
This section is non-normative.
Accurately
measuring
performance
characteristics
of
web
applications
is
an
important
aspect
of
making
web
applications
faster.
[
NAVIGATION-TIMING-2
NAVIGATION-TIMING
]
and
[
RESOURCE-TIMING-2
RESOURCE-TIMING
]
provide
detailed
request
timing
information
for
the
document
and
its
resources,
which
include
time
when
the
request
was
initiated,
and
various
milestones
to
negotiate
the
connection
and
receive
the
response.
However,
while
the
user
agent
can
observe
the
timing
data
of
the
request
it
has
no
insight
into
how
or
why
certain
stages
of
the
request-response
cycle
have
taken
as
much
time
as
they
have
-
e.g.,
how
the
request
was
routed,
where
the
time
was
spent
on
the
server,
and
so
on.
This
specification
introduces
PerformanceServerTiming
interface,
which
enables
the
server
to
communicate
performance
metrics
about
the
request-response
cycle
to
the
user
agent,
and
a
JavaScript
interface
to
enable
applications
to
collect,
process,
and
act
on
these
metrics
to
optimize
application
delivery.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY , MUST , and SHOULD NOT in this document are to be interpreted as described in BCP 14 [ RFC2119 ] [ RFC8174 ] when, and only when, they appear in all capitals, as shown here.
The Server-Timing header field is used to communicate one or more metrics and descriptions for the given request-response cycle. The ABNF (Augmented Backus-Naur Form) [ RFC5234 ] syntax for the Server-Timing header field is as follows:
Server-Timing = #server-timing-metric
server-timing-metric = metric-name *( OWS ";" OWS server-timing-param )
metric-name = token
server-timing-param = server-timing-param-name OWS "=" OWS server-timing-param-value
server-timing-param-name = token
server-timing-param-value = token / quoted-string
See
[
RFC7230
]
for
definitions
of
#
,
*
,
OWS
,
token
,
and
quoted-string
.
A response MAY have multiple server-timing-metric entries with the same metric-name, and the user agent MUST process and expose all such entries.
The user agent MAY surface provided metrics in any order - i.e. the order of metrics in the HTTP header field is not significant.
This header field is defined with an extensible syntax to allow for future parameters. A user agent that does not recognize particular server-timing-param-name in the Server-Timing header field of a response MUST ignore those tokens and continue processing instead of signaling an error.
To
avoid
any
possible
ambiguity,
individual
server-timing-param-name
s
SHOULD
NOT
appear
multiple
times
within
a
server-timing-metric
.
If
any
server-timing-param-name
is
specified
more
than
once,
only
the
first
instance
is
to
be
considered,
even
if
the
server-timing-param
is
incomplete
or
invalid.
All
subsequent
occurrences
MUST
be
ignored
without
signaling
an
error
or
otherwise
altering
the
processing
of
the
server-timing-metric
.
This
is
the
only
case
in
which
the
ordering
of
parameters
within
a
server-timing-metric
is
considered
to
be
significant.
User
agents
MUST
ignore
extraneous
characters
found
after
a
server-timing-param-value
but
before
the
next
server-timing-param
and
before
the
end
of
the
current
server-timing-metric
.
User
agents
MUST
ignore
extraneous
characters
found
after
a
metric-name
but
before
the
first
server-timing-param
and
before
the
next
server-timing-metric
.
This
specification
establishes
the
server-timing-params
for
server-timing-param-names
"dur"
for
duration
and
"desc"
for
description
,
both
optional.
To minimize the HTTP overhead the provided names and descriptions should be kept as short as possible - e.g. use abbreviations and omit optional values where possible.
Because
there
can
be
no
guarantee
of
clock
synchronization
between
client,
server,
and
intermediaries,
it
is
impossible
to
map
a
meaningful
startTime
onto
the
clients
timeline.
For
that
reason,
any
startTime
attribution
is
purposely
omitted
from
this
specification.
If
the
developers
want
to
establish
a
relationship
between
multiple
entries,
they
can
do
so
by
communicating
custom
data
via
metric
names
and/or
descriptions.
The
server
and/or
any
relevant
intermediaries
are
in
full
control
of
which
metrics
are
communicated
to
the
user
agent
and
when.
For
example,
access
to
some
metrics
may
be
restricted
due
to
privacy
or
security
reasons
-
see
7.
6.
Privacy
and
Security
section.
To parse a server-timing header field given a string field :
Let position be a position variable , initially pointing at the start of field .
Let name be the result of collecting a sequence of code points from field that are not equal to U+003B (;), given position .
Strip leading and trailing ASCII whitespace from name .
If name is an empty string, return null.
Let
metric
be
a
new
PerformanceServerTiming
whose
metric
name
is
name
.
Let params be an empty map .
While position is not at the end of field :
Advance position by 1.
Let paramName be the result of collecting a sequence of code points from field that are not equal to U+003D (=), given position .
Strip leading and trailing ASCII whitespace from paramName .
If paramName is an empty string or params [ paramName ] exists , continue .
Advance position by 1.
Let paramValue be an empty string.
Skip ASCII whitespace within field given position .
If the code point at position within field is U+0022 ("), then:
Set paramValue to the result of collecting an HTTP quoted string from field given position with the extract-value flag set.
Collect a sequence of code points from field that are not equal to U+003B (;), given position . The result is not used.
Otherwise:
Let rawParamValue be the result of collecting a sequence of code points from field that are not equal to U+003B (;), given position .
Let paramValue be the result of stripping rawParamValue .
Return metric .
WebIDL[Exposed=(Window,Worker)]
interface
interface PerformanceServerTiming
{
readonly attribute DOMString name
;
readonly attribute DOMHighResTimeStamp duration
;
readonly attribute DOMString description
;
[Default] object toJSON
();
};
When
toJSON
is
called,
run
[
WEBIDL
]'s
default
toJSON
steps
.
The
name
attribute
MUST
getter
steps
are
to
return
the
DOMString
value
of
the
server-specified
this
's
metric
name.
name
.
The
duration
attribute
MUST
getter
steps
are
to
do
the
following:
The
description
attribute
MUST
getter
steps
are
to
return
this
's
params
[
"desc"
]
if
it
exists
,
otherwise
the
DOMString
value
of
the
server-specified
metric
description,
or
empty
string.
A
PerformanceServerTiming
has
an
associated
string
metric
name
,
initially
set
to
the
empty
string.
A
PerformanceServerTiming
has
an
associated
map
params
,
initially
empty.
PerformanceResourceTiming
interface
The
PerformanceResourceTiming
interface,
which
this
specification
partially
extends,
is
defined
in
[
RESOURCE-TIMING-2
RESOURCE-TIMING
].
WebIDL[Exposed=(Window,Worker)]
partial interface PerformanceResourceTiming
{
readonly attribute
readonly attribute FrozenArray<PerformanceServerTiming
> serverTiming
;
};
The
serverTiming
attribute
returns
a
sequence
of
PerformanceServerTiming
entries.
6.
Process
6.1
Processing
Model
When
processing
the
response
of
the
current
document
,
set
the
serverTiming
attribute
on
the
newly
created
PerformanceNavigationTiming
object
to
the
return
value
of
getter
steps
are
the
server-timing
header
parsing
algorithm
following:
6.1.1
server-timing
header
parsing
algorithm
Given
a
resource
timing
object
,
perform
the
following
steps:
Let
entryList
entries
be
a
new
empty
sequence
list
.
For
each
server-specified
metric
received
from
parsing
the
Server-Timing
header
field
,
perform
the
following
steps:
Let
entry
be
a
new
PerformanceServerTiming
in
this
object.
's
timing
info
's
server-timing
headers
:
Let
metric
be
the
result
of
parsing
to
metric-name.
field
.
If
metric
is
case-insensitively
equal
to
"dur",
or
value
0
if
omitted
or
not
representable
as
a
double.
Set
description
null,
append
to
the
server-timing-param-value
for
the
server-timing-param
where
server-timing-param-name
is
case-insensitively
equal
to
"desc",
or
an
empty
string
if
omitted.
Append
entry
metric
to
entryList
entries
.
Return
entryList
entries
.
This section is non-normative.
The
interfaces
defined
in
this
specification
expose
potentially
sensitive
application
and
infrastructure
information
to
any
web
page
that
has
included
a
resource
that
advertises
server
timing
metrics.
For
this
reason
the
access
to
PerformanceServerTiming
interface
is
restricted
by
the
same
origin
policy
by
default.
Resource
providers
can
explicitly
allow
server
timing
information
to
be
available
by
adding
the
Timing-Allow-Origin
HTTP
response
header,
as
defined
in
[
RESOURCE-TIMING-2
RESOURCE-TIMING
],
that
specifies
the
domains
that
are
allowed
to
access
the
server
metrics.
In
addition
to
using
the
Timing-Allow-Origin
HTTP
response
header,
the
server
can
also
use
relevant
logic
to
control
which
metrics
are
returned,
when,
and
to
whom
-
e.g.
the
server
may
only
provide
certain
metrics
to
correctly
authenticated
users
and
nothing
at
all
to
all
others.
The permanent message header field registry should be updated with the following registrations ([ RFC3864 ]):
This section is non-normative.
> GET /resource HTTP/1.1
> Host: example.com
< HTTP/1.1 200 OK
< Server-Timing: miss, db;dur=53, app;dur=47.2
< Server-Timing: customView, dc;desc=atl
< Server-Timing: cache;desc="Cache Read";dur=23.2
< Trailer: Server-Timing
< (... snip response body ...)
<
Server-Timing:
total;dur=123.4
Name | Duration | Description |
---|---|---|
miss | ||
db | 53 | |
app | 47.2 | |
customView | ||
dc | atl | |
cache | 23.2 | Cache Read |
total | 123.4 |
The
above
header
fields
communicate
six
distinct
metrics
that
illustrate
all
the
possible
ways
for
the
server
to
communicate
data
to
the
user
agent:
metric
name
only,
metric
with
value,
metric
with
value
and
description,
and
metric
with
description.
For
example,
the
above
metrics
may
indicate
that
for
example.com/resource.jpg
fetch:
The application can collect, process, and act on the provided metrics via the provided JavaScript interface:
// serverTiming entries can live on 'navigation' and 'resource' entries
for (const entryType of ['navigation', 'resource']) {
for (const {name: url, serverTiming} of performance.getEntriesByType(entryType)) {
// iterate over the serverTiming array
for (const {name, duration, description} of serverTiming) {
// we only care about "slow" ones
if (duration > 200) {
console.info('Slow server-timing entry =',
JSON.stringify({url, entryType, name, duration, description}, null, 2))
}
}
}
}
This section is non-normative.
Server processing time can be a significant fraction of the total request time. For example, a dynamic response may require one or more database queries, cache lookups, API calls, time to process relevant data and render the response, and so on. Similarly, even a static response can be delayed due to overloaded servers, slow caches, or other reasons.
Today, the user agent developer tools are able to show when the request was initiated, and when the first and last bytes of the response were received. However, there is no visibility into where or how the time was spent on the server, which means that the developer is unable to quickly diagnose if there is a performance bottleneck on the server, and if so, in which component. Today, to answer this question, the developer is required to use different techniques: check the server logs, embed performance data within the response (if possible), use external tools, and so on. This makes identifying and diagnosing performance bottlenecks hard, and in many cases impractical.
Server Timing defines a standard mechanism that enables the server to communicate relevant performance metrics to the client and allows the client to surface them directly in the developer tools - e.g. the requests can be annotated with server sent metrics to provide insight into where or how the time was spent while generating the response.
In addition to surfacing server sent performance metrics in the developer tools, a standard JavaScript interface enables analytics tools to automatically collect, process, beacon, and aggregate these metrics for operational and performance analysis.
Server Timing enables origin servers to communicate performance metrics about where or how time is spent while processing the request. However, the same request and response may also be routed through one or more multiple proxies (e.g. cache servers, load balancers, and so on), each of which may introduce own delays and may want to provide performance metrics into where or how the time is spent.
For example, a CDN edge node may want to report which data center was being used, if the resource was available in cache, and how long it took to retrieve the response from cache or from the origin server. Further, the same process may be repeated by other proxies, thus allowing full end-to-end visibility into how the request was routed and where the time was spent.
Similarly, when a Service Worker is active, some or all of the navigation and resource requests may be routed through it. Effectively, an active Service Worker is a local proxy that is able to reroute requests, serve cached responses, synthesize responses, and more. As a result, Server Timing enables Service Worker to report custom performance metrics about how the request was processed: whether it was fetched from a server or served from local cache, duration of relevant the processing steps, and so on.
This section is non-normative.
This
document
reuses
text
from
the
[
NAVIGATION-TIMING-2
NAVIGATION-TIMING
],
[
RESOURCE-TIMING-2
RESOURCE-TIMING
],
[
PERFORMANCE-TIMELINE-2
],
and
[
RFC6797
]
specifications
as
permitted
by
the
licenses
of
those
specifications.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: