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 is a **proposal** and may change without any notices.
## Introduction Accurately measuring performance characteristics of web applications is an important aspect of making web applications faster. [[!NAVIGATION-TIMING-2]] and [[!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 Server Timing, 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.
## Server Timing Server Timing constitutes of two parts: 1. The `Server-Timing` HTTP header field, which allows the server to communicate performance metrics and descriptions within the response and in a well-defined format. 1. The PerformanceServerTiming interface to allow scripts to collect, process, and act on these metrics to optimize application delivery. ### The `Server-Timing` Header Field 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) syntax for the Server-Timing header field is as follows: ```ABNF Server-Timing = "Server-Timing" ":" #server-timing-metric server-timing-metric = metric [ ";" description ] metric = metric-name [ "=" metric-value ] metric-name = token metric-value = 1\*DIGIT [ "." 1\*DIGIT ] description = token | quoted-string ``` * Each metric MUST have a name. * Metric names MAY be repeated. * Metric names are defined by the server. * Each metric MAY have an optional numeric value. * Each metric MAY have an optional description. * The user agent MAY surface provided metrics in any order - i.e. the order of metrics in the HTTP header field is not significant. See [[!RFC7230]] for definitions of `token`, `DIGIT`, and `quoted-string`.
To minimize the HTTP overhead the provided metrics and descriptions should be kept as short as possible - e.g. use abbreviations and omit optional values where possible.
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 section.
## The PerformanceServerTiming Interface The PerformanceServerTiming interface participates in the [[!PERFORMANCE-TIMELINE-2]] and redefines the semantics of the following attributes of the PerformanceEntry interface:
`name`
This attribute MUST return the resolved URL of the requested resource [[!HTML5]]. This attribute MUST NOT change even if the fetch redirected to a different URL.
`entryType`
This attribute MUST return the DOMString "`server`".
`startTime`
This attribute MUST return value 0.
`duration`
This attribute MUST return a `DOMHighResTimeStamp` [[!HR-TIME-2]] that contains the server-specified metric value, or value 0.
## ServerEntry interface
  interface ServerEntry : PerformanceEntry {
    readonly attribute DOMString metric;
    readonly attribute DOMString description;
    serializer = { inherit, attribute };
  };
  
metric attribute
This attribute MUST return the server-specified metric name.
description attribute
This attribute MUST return the server-specified metric description, or an empty string.
serializer
See [[!WebIDL]] for serializer behavior of `inherit` and `attribute`.
## Extensions to `Performance` Interface The Performance interface is extended with the following methods and attribute:
  partial interface Performance {
    void clearServerTimings();
    void setServerTimingBufferSize(unsigned long maxSize);
    attribute EventHandler onservertimingbufferfull;
  };
  
clearServerTimings() method
This method clears the buffer used to store the current list of PerformanceServerTiming resources.
setServerTimingBufferSize() method
This method, when invoked, MUST set the maximum number of PerformanceServerTiming resources that may be stored in the buffer to the value of the `maxSize` parameter. The buffer is considered to be full if the number of entries in it is greater than or equal to `maxSize`. If this method is not called, the user agent SHOULD store at least 150 PerformanceServerTiming resources in the buffer, unless otherwise specified by the user agent. If the `maxSize` parameter is less than the number of elements currently stored in the buffer, no elements in the buffer are to be removed and the user agent MUST NOT fire the `servertimingbufferfull` event. The maxSize parameter sets the maximum number of PerformanceServerTiming resources that will be stored in the buffer.
onservertimingbufferfull attribute
The event handler for the `servertimingbufferfull` event. Immediately after the buffer used to store the list of PerformanceServerTiming resources becomes full, the user agent MUST fire a simple event named `servertimingbufferfull` that bubbles, isn't cancelable, has no default action, at the `Performance` object [[!NAVIGATION-TIMING-2]].
## Process ### Processing Model
  1. Once the Window object of the current document is created the user agent MUST create a `PerformanceEntryList` object (primary buffer) to store the list of PerformanceServerTiming resources.
  2. Set the primary buffer to a size of 150, unless otherwise specified by the user agent or set by the setServerTimingBufferSize method.
  3. For each server-specified metric received via the Server-Timing header field perform the following steps:
    1. Create a new PerformanceServerTiming object and set entryType to the DOMString `server`.
    2. Set the name to the resolved URL of the requested resource.
    3. Set metric to the server-specified metric name.
    4. Set duration to the server-specified metric value, or value 0.
    5. Set description to the server-specified metric description, or an empty string.
    6. Set startTime to the value 0.
    7. If the primary buffer is full, discard the PerformanceServerTiming object, created in step 3. Otherwise, add it to the primary buffer . If adding it causes the primary buffer to become full, fire the servertimingbufferfull event at the Document.
      1. If the clearServerTimings method is called in the event handler for the servertimingbufferfull event, clear all PerformanceServerTiming objects in the primary buffer.
      2. If the setServerTimingBufferSize method is called in the event handler for the servertimingbufferfull event, set the maximum size of the primary buffer to the `maxSize` parameter. If the `maxSize` parameter is less than the number of elements currently stored in the buffer, no elements in the buffer are to be removed.
The user-agent MUST process Server-Timing header field communicated via a trailer field (see [[!RFC7230]] section 4.1.2) using the same algorithm.

### Cross-origin Resources Cross-origin resources (i.e. non same origin) MUST be included as PerformanceServerTiming objects in the Performance Timeline. If the "timing allow check" algorithm, as defined in [[RESOURCE-TIMING]], fails for a cross-origin resource: Server must return the `Timing-Allow-Origin` HTTP response header, as defined in [[RESOURCE-TIMING]], to allow the user agent to fully expose, to the document origin(s) specified, the values of attributes that would have been set to zero or empty string due to the cross-origin restrictions.
## Privacy and Security 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 `ServerTiming` interface is restricted by the same origin policy by default, as described in . 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]], that species 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.
## IANA Considerations The permanent message header field registry should be updated with the following registrations ([[RFC3864]]): ### Server-Timing
Header field name
Server-Timing
Applicable protocol
http
Status
standard
Author/Change controller
W3C
Specification document
This specification (See Server Timing Header Field)
## Examples
    > GET /resource HTTP/1.1
    > Host: example.com

    < HTTP/1.1 200 OK
    < Server-Timing: miss, db=53, app=47.2;
    < Server-Timing: customView, dc;atl
    < Trailer: Server-Timing
    < (... snip response body ...)
    < Server-Timing: total=123.4
  
Name Value Description
miss
dcatl
db53
app47.2customView
total123.4
The above header fields communicates five 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` fetch: * There was a cache miss. * The request was routed through the "atl" datacenter ("dc"). * The database ("db") time was 53 ms. * The application server ("app") took 47.2ms to process "customView" template or function. * The total time for the request-response cycle on the server was 123.4ms, which is recorded at the end of the response and delivered via a trailer field. The application can collect, process, and act on the provided metrics via the provided JavaScript interface:
  window.performance
    .getEntriesByName('https://example.com/resource.jpg')
    .filter(({ name }) => name === "server")
    .forEach(processServerEntry);
  
## Use cases ### Server timing in developer tools 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. ### Server timing for automated analytics 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. ### Measuring request routing performance 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 server or server from local cache, duration of relevant the processing steps, and so on.
## Acknowledgments This document reuses text from the [[NAVIGATION-TIMING-2]], [[RESOURCE-TIMING]], [[PERFORMANCE-TIMELINE-2]], and [[RFC6797]] specifications as permitted by the licenses of those specifications.