> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lexq.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 성능 프로파일링

> 정책 그룹의 규칙별 지연을 모든 호출에서 측정합니다. 판정은 상대 기준으로만, 값은 지어내지 않습니다.

모든 실행은 *무엇이* 결정됐는지 답합니다. 의사결정 재실행(Decision Replay)은 *무엇이 달라지는지* 답합니다.
성능 프로파일링(Performance Profiling)은 세 번째 질문에 답합니다. **지금 이 버전에서, 각 규칙은 얼마나 빠른가?**

LexQ는 프로덕션에서 지연을 상시 측정합니다. 별도 에이전트나 설정 없이, 모든 플랜에서 동작합니다.

## 측정 방식

| 시리즈                            | 범위             | 측정 대상                            |
| ------------------------------ | -------------- | -------------------------------- |
| 전체 실행 시간                       | **모든 호출**      | 엔진 전 구간: 규칙 로딩, 컴파일, 평가, 동기 액션   |
| 규칙별 조건(Condition) / 액션(Action) | 결정론적 **1% 표본** | 각 규칙의 조건 평가 시간, 선정된 규칙의 액션 실행 시간 |

* **결정론적 샘플링.** 표본 포함 여부는 `traceId`만으로 결정됩니다.
  누구든 같은 판정을 재계산할 수 있고, 우연은 개입하지 않습니다.
* **캐시(Cache) 차원.** 캐시된 규칙으로 실행된 `HIT`와 규칙을 새로 불러와 컴파일까지 수행한
  `MISS`(첫 호출, 배포 직후)는 의도적으로 분리된 분포로 관리합니다. 섞으면 두 신호가 모두 가려집니다.
* **60초 구간.** 관측은 60초 구간 단위로 집계됩니다. 비어 있는 구간은 결측 그대로
  보여주고, 보간하지 않습니다.
* **정직한 백분위수.** 모든 백분위수에는 측정 수(Samples) `n`이 함께 제공됩니다. 각
  백분위수는 그 등수 너머의 관측이 3개 이상일 때만 표시합니다 (`n×(1−q) ≥ 3`, p50은
  6건, p95는 60건, p99는 300건부터). 미달이면 값을 지어내는 대신 유보합니다. API에서는
  `null`, 콘솔에서는 `–`로 표시됩니다.

## 느린 규칙 판정 · 상대 기준만

같은 그룹, 버전, 구간(Phase), 캐시 상태 안에서 규칙의 p50이 **규칙별 p50 중앙값의 10배 이상**이면
느림(Slow)으로 판정합니다. 판정에는 `n ≥ 100`인 규칙이 3개 이상 필요합니다. 이 판정
기준은 백분위수 표시 기준과 별개의 축이라, p99가 아직 유보된 규칙도 느림으로 판정될 수 있습니다.

의도된 선택 두 가지:

1. **절대 임계값 없음.** "느리다"의 기준은 도메인마다 다릅니다. 배치 파이프라인에서 50ms는
   무난하지만 결제 경로에서는 치명적일 수 있습니다. LexQ는 어디에도 밀리초 기준값을 고정해 두지 않습니다.
2. **평균이 아니라 중앙값.** 규칙이 1, 1, 1, 1, 40ms일 때 평균 기준(8.8ms × 10 = 88ms)은
   40ms 규칙이 자신이 끌어올린 평균 뒤에 숨게 합니다. 중앙값 기준(1ms × 10 = 10ms)은 잡아냅니다.

## 콘솔

정책 그룹 상세에서 **성능(Performance)** 탭을 엽니다.

* 기간 프리셋 **1h / 24h / 7d**와 **HIT / MISS** 캐시 토글을 제공합니다. 백분위수별
  색상(p50 / p95 / p99)은 카드·표·차트에서 동일하게 쓰입니다.
* 규칙 표에는 측정 수, 백분위수, 기준 대비 배율(`×1.2`)이 표시되고, 판정되면 **느림** 배지가 함께 붙습니다.
* 규칙을 클릭하면 상세 화면이 열립니다. 구간 × 캐시 상태별 요약과, 점 하나가 60초
  구간 하나인 시계열을 보여줍니다. 점은 구간의 원본값이며, 빈 곳은 그 시간에 실행이
  없었다는 뜻입니다.

## API

파트너 API의 읽기 엔드포인트 2개입니다 (`x-api-key` 인증).

```text theme={null}
GET /api/v1/partners/policy-groups/{groupId}/profile
GET /api/v1/partners/policy-groups/{groupId}/profile/rules/{ruleId}
```

쿼리 파라미터(공통): `versionId`(기본값: 운영 중 버전), `from` / `to`(ISO-8601 시각,
반개구간 `[from, to)`, 기본값: 최근 24시간), `cacheState`(`HIT` | `MISS`, 기본 `HIT`,
개요 전용). 시작이 종료와 같거나 늦으면 `P-035` 오류가 반환됩니다.

응답에서 알아둘 규약:

* 표시 기준(`n×(1−q) ≥ 3`) 미달인 백분위수 필드는 `null`이며, `n`은 항상 포함됩니다. p50은 보이고 p99만 `null`인 응답이 정상입니다.
* 판정 가능한 규칙이 3개 미만이면 `baselines[].status`가 `INSUFFICIENT_COHORT`입니다.
* `droppedRows`는 손상되어 건너뛴 기록 수입니다. 결손은 숨기지 않고 셉니다.

## CLI & MCP

```bash theme={null}
lexq profile <groupId> --format table
lexq profile <groupId> --rule <ruleId>          # 병합 분포 + 60초 구간 시계열
lexq profile <groupId> --cache MISS --from 2026-07-01T00:00:00Z
```

AI 에이전트용 MCP 도구 2종이 같은 데이터를 제공합니다: `lexq_profile_overview`, `lexq_profile_rule`.

## 오버헤드와 보존

프로파일링이 결정 경로를 방해하지 않도록 설계했습니다.

* 기본 1% 샘플링에서 실측 오버헤드: **엔진 p50 기준 +0.12%** (JMH, 규칙 20개 픽스처).
  계측이 실패해도 격리해 집계할 뿐, 결정 경로로는 전파되지 않습니다.
* 구간 데이터는 **35일간** 조회 가능하며 이후 아카이브됩니다. **모든 플랜**에서 제공됩니다.

<Note>
  규칙별 상세는 1% 표본에서 수집되므로 트래픽이 적은 그룹은 규칙 단위 백분위수가 천천히
  쌓입니다. 전체 실행 시간은 모든 호출에서 기록됩니다. `–`는 기능이 빠진 것이 아니라,
  시스템이 추측을 거부한다는 표시입니다.
</Note>
