서버 타이밍

W3C 워킹 드래프트,

이 문서에 대한 추가 정보
이 버전:
https://www.w3.org/TR/2026/WD-server-timing-20260407/
최신 발표 버전:
https://www.w3.org/TR/server-timing/
에디터의 드래프트:
https://w3c.github.io/server-timing/
이전 버전:
히스토리:
https://www.w3.org/standards/history/server-timing/
피드백:
public-web-perf@w3.org 제목 라인: “[server-timing] … 메시지 주제 …” (아카이브)
GitHub
테스트 스위트:
http://w3c-test.org/server-timing/
에디터:
요아브 바이스 (Shopify)
이전 에디터:
(Akamai)
일리야 그리고릭 (Google)

개요

이 명세는 서버가 요청-응답 사이클의 성능 지표를 사용자 에이전트에 전달할 수 있도록 합니다. 또한 애플리케이션이 이러한 지표를 수집, 처리, 활용하여 앱 전달을 최적화할 수 있게 해주는 JavaScript 인터페이스를 표준화합니다.

이 문서의 상태

이 섹션은 이 문서가 발표된 시점의 상태를 설명합니다. W3C의 최신 발표 목록과 이 기술 리포트의 최신 개정본은 W3C 표준 및 초안 인덱스에서 확인할 수 있습니다.

이 문서는 Web Performance Working Group 에서 워킹 드래프트로, 추천 경로를 통해 발표되었습니다. 워킹 드래프트로 출판된다고 해서 W3C 및 멤버의 지지를 의미하지는 않습니다.

이 문서는 초안이며, 언제든지 다른 문서에 의해 갱신, 대체 또는 폐기될 수 있습니다. 진행 중인 작업 외의 인용은 적합하지 않습니다.

GitHub 이슈에서 이 명세에 대한 논의가 권장됩니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서에 따라 관리됩니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C는 그룹 결과물과 관련해 공개된 특허 공개 목록을 유지합니다. 해당 페이지에는 특허 공개 방법도 안내되어 있습니다. 실제로 특허에 대한 정보를 가진 사람은 그 특허가 필수 청구항을 포함한다고 믿는 경우, W3C 특허 정책 6장에 따라 정보를 공개해야 합니다.

1. 소개

이 섹션은 비규범적입니다.

웹 애플리케이션의 성능 특성을 정확하게 측정하는 것은 웹 애플리케이션을 더 빠르게 만드는 중요한 부분입니다. [NAVIGATION-TIMING][RESOURCE-TIMING]은 문서와 그 리소스에 대한 상세한 요청 타이밍 정보를 제공합니다. 여기에는 요청이 시작된 시간, 그리고 연결 협상 및 응답 수신을 위한 다양한 단계가 포함됩니다. 하지만 사용자 에이전트가 요청의 타이밍 데이터를 관찰할 수 있어도 요청-응답 사이클의 특정 단계가 왜 또는 어떻게 오래 걸렸는지에 대한 내부 정보를 알 수 없습니다. 예를 들어, 요청이 어떻게 라우팅되었는지, 서버에서 시간이 어떻게 쓰였는지 등입니다.

이 명세는 PerformanceServerTiming 인터페이스를 소개하며, 서버가 요청-응답 사이클의 성능 지표를 사용자 에이전트에 전달하고, 애플리케이션이 이러한 지표를 수집·처리·활용하여 앱 전달을 최적화할 수 있도록 하는 JavaScript 인터페이스를 표준화합니다.

2. Server-Timing 헤더 필드

Server-Timing 헤더 필드는 특정 요청-응답 사이클에 대해 하나 이상의 지표와 설명을 전달하는 데 사용됩니다. [RFC5234]의 ABNF(확장된 Backus-Naur Form) 구문에서 Server-Timing 헤더 필드는 다음과 같이 정의됩니다:

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

[RFC7230]에서 #, *, OWS, token, quoted-string 정의를 참고하십시오.

응답에는 동일한 metric-name을 가진 여러 server-timing-metric 항목이 존재할 수 있으며, 사용자 에이전트는 모든 항목을 처리하고 노출해야 합니다.

사용자 에이전트는 제공된 지표를 임의의 순서로 표시할 수 있습니다. 즉, HTTP 헤더 필드 내의 지표 순서는 중요하지 않습니다.

이 헤더 필드는 미래의 파라미터를 허용하기 위해 확장 가능한 구문으로 정의됩니다. 응답의 Server-Timing 헤더 필드에서 특정 server-timing-param-name을 인식하지 못하는 사용자 에이전트는 해당 토큰을 무시하고 오류 신호 없이 계속 처리해야 합니다.

모호성을 피하기 위해, 개별 server-timing-param-nameserver-timing-metric 내에서 여러 번 나타나지 않아야 합니다. 만약 server-timing-param-name이 여러 번 지정되면 첫 번째 인스턴스만 고려하고, server-timing-param가 불완전하거나 유효하지 않더라도 모든 후속 등장들은 오류 신호 없이 무시하며, server-timing-metric 처리에도 영향을 주지 않습니다. 이 경우만 server-timing-metric 내 파라미터의 순서가 의미를 가집니다.

사용자 에이전트는 server-timing-param-value 뒤에서 다음 server-timing-param 및 현재 server-timing-metric의 끝 전까지 발견된 불필요한 문자를 무시해야 합니다.

사용자 에이전트는 metric-name 뒤에서 첫 server-timing-param 및 다음 server-timing-metric 전까지 발견된 불필요한 문자를 무시해야 합니다.

이 명세는 server-timing-param-names로 "dur"(duration)과 "desc"(description)을 정의합니다. 둘 다 선택 사항입니다.

Server-Timing 헤더 필드 파싱 동작은 문자열 field가 주어졌을 때 다음과 같다:

  1. position포지션 변수로 지정하고, 처음에는 field의 처음을 가리키게 한다.

  2. name코드 포인트 시퀀스 수집의 결과로, field에서 U+003B(;)가 아닌 문자들을 position에 따라 수집한다.

  3. 앞뒤 ASCII 공백 제거name에 대해 수행한다.

  4. name이 빈 문자열이면 null을 반환한다.

  5. metric을 새 PerformanceServerTiming 객체로 하고, metric namename으로 지정한다.

  6. params를 빈 순서 있는 맵으로 설정한다.

  7. positionfield의 끝에 도달할 때까지:

    1. position을 1 더한다.

    2. paramName코드 포인트 시퀀스 수집의 결과로, field에서 U+003D(=)가 아닌 문자들을 position에서 수집한다.

    3. 앞뒤 ASCII 공백 제거paramName에 대해 수행한다.

    4. paramName이 빈 문자열이거나 params[paramName]이 존재하면, continue한다.

    5. position을 1 더한다.

    6. paramValue를 빈 문자열로 설정한다.

    7. ASCII 공백 건너뛰기field에서 position에 대해 수행한다.

    8. 만약 fieldposition 위치의 코드 포인트가 U+0022(")라면:

      1. paramValueHTTP quoted string 수집 결과로 설정한다, fieldposition, 그리고 extract-value flag가 설정된 상태로 수행한다.

      2. 코드 포인트 시퀀스 수집field에서 U+003B(;)가 아닌 문자에 대해 position에서 수행한다. 결과는 사용하지 않는다.

    9. 그 외의 경우:

      1. rawParamValue코드 포인트 시퀀스 수집 결과로, field에서 U+003B(;)가 아닌 문자들을 position에서 수집한다.

      2. paramValue공백 제거rawParamValue에 대해 수행한 결과로 설정한다.

  8. Set metricparamsparams로 설정한다.

  9. metric을 반환한다.

3. PerformanceServerTiming 인터페이스

[Exposed=(Window,Worker)]
interface PerformanceServerTiming {
  readonly attribute DOMString name;
  readonly attribute DOMHighResTimeStamp duration;
  readonly attribute DOMString description;
  [Default] object toJSON();
};

toJSON이 호출되면, [WEBIDL]기본 toJSON 단계를 실행한다.

3.1. name 속성

name getter 단계는 thismetric name을 반환하도록 한다.

3.2. duration 속성

duration getter 단계는 다음을 수행한다:

  1. thisparams["dur"]이 존재하지 않으면, 0을 반환한다.

  2. durthisparams["dur"]을 부동 소수점 숫자 값 파싱 규칙을 사용하여 파싱한 결과로 한다.

  3. dur이 오류이면 0을, 그렇지 않으면 dur을 반환한다.

duration 속성은 DOMHighResTimeStamp이므로, 보통 밀리초 단위의 duration을 나타낸다. 하지만 실제로 강제할 수 없기 때문에, duration 속성은 임의의 시간 단위를 나타낼 수 있으며, 밀리초 단위로 표현하는 것이 권장된다.

3.3. description 속성

description getter 단계는 thisparams["desc"]이 존재한다면 반환하고, 그렇지 않으면 빈 문자열을 반환한다.

PerformanceServerTiming 객체는 연관된 문자열 metric name을 가지며, 처음에는 빈 문자열로 설정된다.

PerformanceServerTiming 객체는 연관된 ordered map params를 가지며, 처음에는 비어 있다.

3.4. PerformanceResourceTiming 인터페이스 확장

PerformanceResourceTiming 인터페이스(이 명세가 부분적으로 확장하는)는 [RESOURCE-TIMING]에서 정의된다.

[Exposed=(Window,Worker)]
partial interface PerformanceResourceTiming {
  readonly attribute FrozenArray<PerformanceServerTiming> serverTiming;
};

3.5. serverTiming 속성

serverTiming getter 단계는 다음과 같다:

  1. entries를 새로운 목록으로 한다.

  2. 각각의 field에 대하여 thistiming infoserver-timing headers에서:

    1. metric해석field의 결과로 한다.

    2. 만약 metric이 null이 아니라면, append metricentries에 추가한다.

  3. entries를 반환한다.

4. 프라이버시 및 보안

이 섹션은 비규범적입니다.

이 명세에서 정의된 인터페이스는 서버 타이밍 지표를 광고하는 리소스를 포함한 웹 페이지에 잠재적으로 민감한 애플리케이션 및 인프라 정보를 노출할 수 있습니다. 이 때문에 PerformanceServerTiming 인터페이스에 대한 접근은 기본적으로 동일 출처 정책에 의해 제한됩니다. 리소스 제공자는 [RESOURCE-TIMING]에서 정의한 Timing-Allow-Origin HTTP 응답 헤더를 추가하여 특정 도메인에 서버 지표 접근을 명시적으로 허용할 수 있지만, 사용자 에이전트는 동일 출처 정책 제한을 계속 유지할 수 있습니다.

Timing-Allow-Origin HTTP 응답 헤더 외에도 서버는 관련 로직을 통해 어떤 지표를 언제, 누구에게 반환할지 제어할 수 있습니다. 예를 들어, 서버는 특정 메트릭을 인증된 사용자에게만 제공하고, 그 외에는 아무 것도 제공하지 않을 수 있습니다.

5. IANA 고려사항

영구 메시지 헤더 필드 레지스트리는 다음 등록 항목으로 업데이트되어야 합니다 ([RFC3864]):

5.1. Server-Timing 헤더 필드

헤더 필드 이름
Server-Timing
적용 프로토콜
http
상태
standard
작성자/변경 컨트롤러
W3C
명세 문서
이 명세 (See Server-Timing 헤더 필드)

6. 예시

이 섹션은 비규범적입니다.
> 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
이름 지속 시간 설명
miss
db 53
app 47.2
customView
dc atl
cache 23.2 Cache Read
total 123.4

위 헤더 필드는 서버가 데이터 전달 방식의 모든 사례(지표 이름만, 값이 있는 지표, 값 및 설명이 있는 지표, 설명만 있는 지표)를 보여주는 여섯 가지 구분된 지표를 제공합니다. 예를 들어, 위 지표는 example.com/resource.jpg fetch에 대해 다음을 나타냅니다:

  1. 캐시 미스가 발생했다.
  2. 요청이 "atl" 데이터센터("dc")를 경유했다.
  3. 데이터베이스("db") 시간은 53ms였다.
  4. 캐시 읽기는 23.2ms 걸렸다.
  5. 애플리케이션 서버("app")가 "customView" 템플릿이나 기능 처리에 47.2ms를 소요했다.
  6. 요청-응답 사이클의 서버 총 시간은 123.4ms였다. 이는 응답의 마지막에 trailer 필드로 전달된다.

애플리케이션은 제공된 JavaScript 인터페이스를 통해 지표를 수집, 처리, 활용할 수 있습니다:

// serverTiming 항목은 'navigation'과 'resource' entry에서 사용될 수 있음
for (const entryType of ['navigation', 'resource']) {
  for (const {name: url, serverTiming} of performance.getEntriesByType(entryType)) {
    // serverTiming 배열 반복
    for (const {name, duration, description} of serverTiming) {
      // "느린" 항목만 관심 있음
      if (duration > 200) {
        console.info('느린 server-timing 항목 =',
          JSON.stringify({url, entryType, name, duration, description}, null, 2))
      }
    }
  }
}

7. 활용 사례

이 섹션은 비규범적입니다.

7.1. 개발자 도구의 서버 타이밍

서버 처리 시간은 전체 요청 시간의 상당한 부분을 차지할 수 있습니다. 예를 들어, 동적 응답은 하나 이상의 데이터베이스 쿼리, 캐시 조회, API 호출, 관련 데이터 처리 및 응답 렌더링 등 여러 단계가 필요할 수 있습니다. 또한 정적 응답도 서버 과부하, 느린 캐시 등의 이유로 지연될 수 있습니다.

현재 사용자 에이전트 개발자 도구는 요청이 언제 시작되고 응답의 첫 바이트와 마지막 바이트를 언제 받았는지 보여줄 수 있습니다. 하지만 서버에서 시간이 어디에 어떻게 소비되었는지 볼 수 없으므로, 개발자가 서버에 성능 병목이 있는지, 있다면 어떤 구성 요소에서 발생했는지 빠르게 진단할 수 없습니다. 현재 이 문제를 해결하려면 개발자는 서버 로그 확인, 응답 내용에 성능 데이터 포함(가능한 경우), 외부 도구 사용 등이 필요합니다. 이러한 절차는 성능 병목 진단을 어렵게 하며, 실질적으로 비현실적인 경우가 많습니다.

서버 타이밍은 서버가 클라이언트에 관련 성능 지표를 전달할 수 있게 하는 표준 메커니즘을 정의하며, 클라이언트는 이를 개발자 도구에서 직접 노출할 수 있습니다. 즉, 요청에 서버가 제공한 지표가 주석으로 붙어 응답 생성 중 어디에 어떻게 시간이 소비되었는지 알 수 있습니다.

7.2. 자동화 분석을 위한 서버 타이밍

서버가 보낸 성능 지표를 개발자 도구에 노출하는 것 외에도 표준 JavaScript 인터페이스를 통해 분석 도구가 자동으로 지표를 수집, 처리, 비콘, 집계하여 운영 및 성능 분석에 활용할 수 있습니다.

7.3. 요청 라우팅 성능 측정

서버 타이밍은 원본 서버가 요청 처리 중 어디에서, 어떻게 시간이 소비되었는지에 대한 성능 지표를 전달할 수 있게 해줍니다. 하지만 동일한 요청과 응답이 하나 이상의 여러 프록시(예: 캐시 서버, 로드 밸런서 등)를 경유할 수도 있는데, 각 프록시는 자체 지연을 유발할 수 있으며 시간 소비에 대한 자체 성능 지표를 함께 제공하고 싶을 수 있습니다.

예를 들어, CDN 엣지 노드는 어느 데이터센터를 사용했는지, 리소스가 캐시에 있었는지, 캐시 혹은 원본 서버에서 응답을 받는 데 걸린 시간을 보고하고 싶을 수 있습니다. 또한 다른 프록시들도 동일한 작업을 반복할 수 있어 전체 요청의 경로와 시간 사용에 대한 완전한 엔드-투-엔드 가시성을 제공합니다.

마찬가지로 서비스 워커가 활성화된 경우 탐색 및 리소스 요청의 일부 또는 전부가 이를 경유할 수 있습니다. 실제로 활성화된 서비스 워커는 로컬 프록시로 요청을 재경로하고, 캐시된 응답을 제공하거나 응답을 합성할 수 있습니다. 결과적으로 서버 타이밍은 서비스 워커가 요청 처리 방식(예: 서버 fetch 또는 로컬 캐시 제공, 각 단계의 소요 시간 등)에 대한 맞춤 성능 지표를 보고할 수 있게 해줍니다.

8. 감사의 글

이 섹션은 비규범적입니다.

이 문서는 [NAVIGATION-TIMING], [RESOURCE-TIMING], [PERFORMANCE-TIMELINE-2], [RFC6797] 명세의 텍스트를 라이선스가 허용하는 범위 내에서 재사용합니다.

적합성

문서 관례

적합성 요건은 설명적 단정문과 RFC 2119 용어를 조합하여 표현합니다. 본 문서의 규범적 부분에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL”과 같은 주요 단어들은 RFC 2119에서 설명된 대로 해석해야 합니다. 다만 가독성을 위해, 이 단어들은 명세 전체에서 모두 대문자로 표시되지 않습니다.

이 명세의 텍스트는 명시적으로 비규범적임을 밝힌 섹션, 예시, 참고를 제외하면 모두 규범적입니다. [RFC2119]

이 명세의 예시들은 “for example”라는 말로 도입되거나, class="example" 속성으로 규범 텍스트와 구분됩니다. 예를 들면 다음과 같습니다:

이것은 비규범적 예시입니다.

비규범적 참고는 “Note”라는 단어로 시작하며, class="note" 속성으로 규범 텍스트와 구분됩니다. 예를 들면 다음과 같습니다:

Note, 이것은 비규범적 참고입니다.

적합 알고리즘

알고리즘 내에서 명령형으로 표현된 요건(예: "선행 공백 문자를 제거한다" 또는 "false를 반환하고 이 단계를 중단한다")은 도입부에 사용된 주요 단어("must", "should", "may" 등)의 의미대로 해석해야 합니다.

알고리즘 또는 특정 단계로 표현된 적합성 요건은 결과만 동일하다면 어떤 방식으로든 구현될 수 있습니다. 특히, 이 명세에 정의된 알고리즘은 이해하기 쉽도록 작성된 것이며 성능을 최우선으로 고려하지는 않았습니다. 구현자는 성능 최적화를 권장합니다.

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참조 문헌

규범적 참조

[FETCH]
Anne van Kesteren. Fetch 표준. Living Standard. URL: https://fetch.spec.whatwg.org/
[HR-TIME-3]
Yoav Weiss. 고해상도 시간. 2026년 3월 24일. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. HTML 표준. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 표준. Living Standard. URL: https://infra.spec.whatwg.org/
[RESOURCE-TIMING]
Yoav Weiss; Noam Rosenthal. 리소스 타이밍. 2026년 3월 23일. CRD. URL: https://www.w3.org/TR/resource-timing/
[RFC2119]
S. Bradner. RFC에서 요구 수준을 나타내기 위한 주요 단어. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC3864]
G. Klyne; M. Nottingham; J. Mogul. 메시지 헤더 필드 등록 절차. 2004년 9월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc3864
[RFC5234]
D. Crocker, Ed.; P. Overell. 구문 명세를 위한 확장 BNF: ABNF. 2008년 1월. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc5234
[RFC7230]
R. Fielding, Ed.; J. Reschke, Ed.. 하이퍼텍스트 전송 프로토콜 (HTTP/1.1): 메시지 구문 및 라우팅. 2014년 6월. Proposed Standard. URL: https://httpwg.org/specs/rfc7230.html
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 표준. Living Standard. URL: https://webidl.spec.whatwg.org/

참고용 참조

[NAVIGATION-TIMING]
Zhiheng Wang. Navigation Timing. 2012년 12월 17일. REC. URL: https://www.w3.org/TR/navigation-timing/
[PERFORMANCE-TIMELINE-2]
Nicolas Pena Moreno. Performance Timeline. 2025년 5월 21일. CRD. URL: https://www.w3.org/TR/performance-timeline/
[RFC6797]
J. Hodges; C. Jackson; A. Barth. HTTP Strict Transport Security (HSTS). 2012년 11월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6797

IDL 색인

[Exposed=(Window,Worker)]
interface PerformanceServerTiming {
  readonly attribute DOMString name;
  readonly attribute DOMHighResTimeStamp duration;
  readonly attribute DOMString description;
  [Default] object toJSON();
};

[Exposed=(Window,Worker)]
partial interface PerformanceResourceTiming {
  readonly attribute FrozenArray<PerformanceServerTiming> serverTiming;
};

MDN

PerformanceResourceTiming/serverTiming

In all current engines.

Firefox61+Safari16.4+Chrome65+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PerformanceServerTiming/description

In all current engines.

Firefox61+Safari16.4+Chrome65+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PerformanceServerTiming/duration

In all current engines.

Firefox61+Safari16.4+Chrome65+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PerformanceServerTiming/name

In all current engines.

Firefox61+Safari16.4+Chrome65+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PerformanceServerTiming/toJSON

In all current engines.

Firefox61+Safari16.4+Chrome65+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

PerformanceServerTiming

In all current engines.

Firefox61+Safari16.4+Chrome65+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Headers/Server-Timing

Firefox61+Safari?Chrome65+
Opera?Edge79+
Edge (Legacy)NoneIENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?