그룹별 p95를 평균내면 전체 p95가 될까?

이 카테고리 글 목록

전체글 보기

서버 A의 p95가 1,000ms이고 B는 2,000ms라면 전체 p95는 1,500ms일까? 그룹별 p95의 단순평균도, 요청 수를 가중치로 준 평균도 전체 p95를 일반적으로 복원하지 못한다. 원시 요청 시간을 합쳐 다시 분위수를 계산하거나, 합칠 수 있는 분포 집계 자료로 추정해야 한다.

여기서는 설명용 합성 요청만 사용한다. 실제 서버·AI 모델의 속도나 운영 SLO를 측정한 결과가 아니다. 작은 표본으로 계산 원리를 보여 주며, 미래 요청의 p95를 추정하거나 통계적 신뢰도를 입증하지 않는다.

먼저 p95를 계산하는 규칙을 고정한다

이 글의 p95는 시간을 오름차순으로 정렬한 뒤 ceil(0.95 × n)번째 값을 고른다. ceil은 올림이고 순서는 1부터 센다. 이를 최근접 순위(nearest-rank) 방식으로 부르며, R 공식 문서의 type 1이 설명하는 경험적 누적분포의 역함수에 해당한다. 이 글은 그 정의를 JavaScript로 구현했으며 R 자체를 실행한 결과는 아니다.

10건이면 10번째, 20건이면 19번째 값이다. 같은 값이 여러 번 있을 수 있으므로 ‘p95보다 느린 요청이 반드시 정확히 5%’라고 읽지 않는다. NIST의 백분위수 설명처럼 표본 분위수에는 여러 계산 방식이 있다. 도구가 보간 방식을 쓰면 같은 입력에서도 값이 달라질 수 있어 방법과 표본 수를 같이 적어야 한다.

같은 그룹 요약값인데 전체 p95가 다른 두 경우

다음 두 경우에서 A는 언제나 ‘100ms 9건과 1,000ms 1건’이다. B만 내부 분포가 다르다. ×는 해당 값이 반복되는 건수를 뜻한다.

서로 다른 합성 원시 분포와 같은 그룹별 요약값
입력 묶음 원시 시간(ms) 건수 합계 / 평균(ms) p95(ms)
공통 A 100 × 9, 1,000 × 1 10 1,900 / 190 1,000
경우 1의 B 200 × 9, 2,000 × 1 10 3,800 / 380 2,000
경우 2의 B 25 × 8, 1,600 × 1, 2,000 × 1 10 3,800 / 380 2,000

두 경우 모두 A·B의 건수, 합계, 평균, p95가 각각 같다. 전체 20건의 평균도 5,700 ÷ 20 = 285ms로 같다. 하지만 전체를 정렬하면 경우 1의 19번째는 1,000ms이고 경우 2의 19번째는 1,600ms다. 그룹별 건수·평균·p95까지 보관했어도 이번 두 원시 분포를 구별할 수 없다.

그룹 p95의 평균은 두 경우 모두 (1,000 + 2,000) ÷ 2 = 1,500ms다. 건수가 똑같아서 요청 수 가중평균도 1,500ms가 된다. 이 값은 이번 두 경우의 전체 p95 어느 쪽과도 일치하지 않는다. 평균값 285ms 역시 꼬리 분포가 같다는 증거가 되지 않는다.

하나의 카드 묶음에서 두 결과 목록으로 화살표가 나뉘고 돋보기가 차이를 살펴보는 삽화
서로 다른 결과를 대조하는 맥락으로 재사용한 기존 AI 생성 개념도. p95의 순위·요청 수·지연 분포를 그린 도표나 측정 화면은 아니다.

복사한 코드로 두 분포를 다시 정렬한다

다음 본문 코드를 Windows의 Node.js v24.15.0에서 실행했다. 입력은 비어 있지 않은 유한한 양수 배열이며 단위는 모두 ms다. 별도 라이브러리나 모니터링 서버 없이 이 합성 예만 검산한다.

const mean = xs => xs.reduce((s, x) => s + x, 0) / xs.length;
function p95(xs) {
  const sorted = [...xs].sort((a, b) => a - b);
  return sorted[Math.ceil(0.95 * sorted.length) - 1];
}
const a = [...Array(9).fill(100), 1000];
const b1 = [...Array(9).fill(200), 2000];
const b2 = [...Array(8).fill(25), 1600, 2000];

for (const [name, b] of [["case1", b1], ["case2", b2]]) {
  const pooled = [...a, ...b];
  console.log(JSON.stringify({
    name, nA: a.length, nB: b.length,
    meanA: mean(a), meanB: mean(b),
    p95A: p95(a), p95B: p95(b),
    meanOfP95: (p95(a) + p95(b)) / 2,
    pooledMean: mean(pooled), pooledP95: p95(pooled)
  }));
}
{"name":"case1","nA":10,"nB":10,"meanA":190,"meanB":380,"p95A":1000,"p95B":2000,"meanOfP95":1500,"pooledMean":285,"pooledP95":1000}
{"name":"case2","nA":10,"nB":10,"meanA":190,"meanB":380,"p95A":1000,"p95B":2000,"meanOfP95":1500,"pooledMean":285,"pooledP95":1600}

20건의 p95는 여기서 두 번째로 큰 값이다. 표본이 작아서 일부 값의 위치가 결과를 크게 바꿀 수 있음을 보여 주는 예이기도 하다. 이 두 출력을 실제 서비스의 안정성이나 특정 제품의 분위수 정확도로 확대하지 않는다.

전체 p95가 필요하면 어떤 자료를 남겨야 하나

Prometheus 공식 문서는 미리 계산한 summary 분위수의 통합과 histogram 분포 집계를 구별한다. 각 인스턴스의 p95 숫자를 평균내는 대신, 같은 관측 범위의 원시 표본이나 집계 가능한 분포 표현을 사용해야 한다.

가지고 있는 자료에 따라 가능한 판단
보관 자료 전체 p95 계산의 범위
그룹별 p95와 건수만 일반적으로 복원 불가. 이번 반례에서는 평균·합계도 추가했지만 부족하다.
중복 없는 전체 원시 요청 시간 기간·단위·포함 조건을 맞추고 명시한 분위수 방식으로 다시 계산한다.
같은 경계의 classic histogram 버킷 건수 같은 관측 범위에서 해당 버킷들을 합친 뒤 분위수를 추정할 수 있다. 원시 값의 정확한 재현과 구별한다.
일부 요청만 추출한 표본 그 표본의 분위수다. 전체 트래픽을 대표하는지 별도 근거가 필요하다.

classic histogram의 버킷은 상한 이하의 관측을 세는 누적 건수다. 여기서 합친다는 것은 같은 상한 경계끼리 서버 간 건수를 더한다는 뜻이며, 서로 다른 경계의 누적 건수를 모두 더해 전체 요청 수로 삼는다는 뜻이 아니다.

버킷 내부의 정확한 요청 시간은 histogram에 남지 않는다. histogram_quantile 공식 설명은 분위수가 버킷 경계와 일치하지 않을 때 내부 값을 보간하는 방식을 설명한다. 따라서 버킷으로 구한 근사값을 원시 표본의 위 19번째 값과 같은 종류의 실측값으로 적지 않는다. 버킷 경계가 다르면 단순히 같은 번호의 버킷을 더하지 말고 사용하는 형식의 호환·변환 규칙을 확인한다.

요청 완료 시간과 첫 토큰 시간, 성공만 포함한 자료와 타임아웃까지 포함한 자료는 같은 분포가 아니다. 서버별 자료가 같은 기간을 다루는지도 확인한다. 이번 글은 Prometheus 설치나 실제 쿼리 실행을 검증한 안내가 아니라 원시 분포와 요약값의 차이를 설명하는 계산 예다.

긴 LLM 컨텍스트의 비용·지연 판단에서 p95는 입력 토큰과 함께 볼 운영 신호로 등장한다. 그 신호를 여러 서버에 걸쳐 보고하려면 전체 분위수를 어떤 입력에서 계산했는지 먼저 맞춰야 한다. 이상 징후의 원인과 대응은 LLM 운영 대응 기준과 연결하되, 분위수 계산만으로 원인이 확정됐다고 하지 않는다.

자주 묻는 질문

요청 수로 가중하면 그룹 p95를 합칠 수 있나요?

가중평균은 값의 정렬 순서를 복원하지 않는다. 이번에는 두 그룹의 건수가 같아서 가중평균도 1,500ms였지만 전체 p95는 1,000ms 또는 1,600ms였다.

p95가 최대값과 같으면 계산이 틀린 건가요?

이 글의 방식에서 10건의 p95 순위는 ceil(9.5) = 10이므로 최대값과 같다. 표본 수와 분위수 정의를 확인하고, 작은 표본의 p95를 장기 트래픽의 안정적인 추정치처럼 제시하지 않는다.

p95가 같으면 두 서비스의 꼬리 지연도 같은가요?

같은 지점의 값 하나만 같을 수 있다. 그보다 느린 요청의 값·건수, p99, 타임아웃 포함 조건 등을 별도로 봐야 한다. 어떤 추가 자료가 필요한지는 실제 운영 질문에 맞춰 정한다.

이 카테고리의 다른 글

전체글 보기

댓글 남기기