Timing-Allow-Origin

The HTTP Timing-Allow-Origin response header controls which Origins are allowed to see detailed timing data from the Resource Timing API for cross-origin resources.

Usage

Browsers expose detailed performance timing for same-origin resources through the PerformanceResourceTiming interface. For cross-origin resources, the same-origin policy restricts access by zeroing out most timing attributes. DNS lookup time, TCP connect duration, TLS handshake time, request start, response start, and transfer size all return 0 for cross-origin requests by default.

The Timing-Allow-Origin header lifts this restriction. When a server includes the header with a matching origin value or wildcard, the browser exposes the full set of timing attributes to JavaScript running on the allowed origin. This gives Real User Monitoring (RUM) tools and performance scripts visibility into the loading behavior of third-party resources like CDN assets, fonts, and analytics scripts.

Without the header, the following PerformanceResourceTiming attributes are zeroed for cross-origin resources: redirectStart, redirectEnd, domainLookupStart, domainLookupEnd, connectStart, connectEnd, requestStart, responseStart, secureConnectionStart, transferSize, encodedBodySize, decodedBodySize, firstInterimResponseStart, and finalResponseHeadersStart. The nextHopProtocol attribute returns an empty string.

The firstInterimResponseStart attribute is particularly relevant for measuring 103 Early Hints performance. This timestamp records when the browser received the first byte of an interim 1xx response. For cross-origin resources, the value returns 0 unless the server sends Timing-Allow-Origin. Measuring the gap between requestStart and firstInterimResponseStart reveals how quickly the server delivered Early Hints before the final response arrived.

const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    const earlyHints =
      entry.firstInterimResponseStart
        - entry.requestStart;
    if (earlyHints > 0) {
      console.log(
        `${entry.name}: Early Hints in ${earlyHints}ms`
      );
    }
  });
});
observer.observe({ type: "resource", buffered: true });

The header also unlocks the Server-Timing serverTiming property on cross-origin resources. Without Timing-Allow-Origin, server timing entries are not exposed to the requesting origin.

Multiple origins are specified as comma-separated values. The wildcard * grants access to all origins. The header is processed during fetch and applies to both fresh and cached responses. When a cached response is revalidated, the header value from the revalidation response takes precedence.

Values

Origin

One or more specific Origins allowed to access timing data. Multiple origins are comma-separated.

* (wildcard)

The wildcard grants timing data access to all origins. Common on public CDN resources and static asset hosts where timing visibility has no privacy implications.

Example

Granting timing access to a specific analytics origin. Only scripts running on https://analytics.example.re see full timing data for this resource.

Timing-Allow-Origin: https://analytics.example.re

Granting timing access to multiple origins. Both the main site and the monitoring service see timing attributes.

Timing-Allow-Origin: https://www.example.re,
  https://monitoring.example.re

A CDN serving public static assets grants timing access to all origins. Any page loading resources from this CDN sees full timing data, enabling RUM tools to measure DNS, TLS, and response times for third-party assets.

Timing-Allow-Origin: *

Pairing Timing-Allow-Origin with Server-Timing exposes both network-level and server-level performance data to cross-origin consumers. The timing header unlocks the serverTiming property containing the custom metrics.

Timing-Allow-Origin: *
Server-Timing: cdn-cache;desc="HIT", edge;dur=2

Takeaway

The Timing-Allow-Origin header controls cross-origin access to Resource Timing API data, enabling performance monitoring of third-party resources. Without the header, browsers zero out timing attributes for cross-origin requests to prevent information leakage.

See also

Last updated: March 5, 2026