Claude Code 프롬프트 캐시 유실을 각 요청의 청구 필드로 판정해, 보고한 기계 단위로 추적한다. 기계 1대가 1행이고, 같은 기계의 두 번째 제출은 행을 늘리지 않고 기존 행을 갱신한다. 아래 모든 수치는 자발적 제출자의 브라우저에서 로컬로 파싱되어, 본인이 승인한 집계 숫자만 제출된 것이다.
짧은 경위. 헤드라인에 불리한 사실도 함께 적는다.
2026년 봄부터 일부 Claude Code 사용자에게서 사용량이 비정상적으로 빨리 소진되는 일이 반복됐다. 5시간 한도 창이 수십 분 만에 바닥나는 수준이었다. 5월의 GitHub 신고(#63282)는 응답 없이 자동으로 닫혔다.
8월, 서버가 로컬 세션 로그에 직접 남기는 진단 필드 message.diagnostics.cache_miss_reason이 확인됐다. 이때부터 유실을 체감이 아니라 서버 기록으로 판정할 수 있게 됐다.
정직한 반론도 적어 둔다: 원시 집계의 대부분(운영자 데이터 기준 78%)은 장시간 유휴 후의 정당한 만료였다. 이 사이트는 그것을 제외하고 TTL 안쪽 유실만 센다.
통제된 재현에서는 같은 기계의 4개 세션이 같은 1분 안에 동시에 캐시를 잃었고, 생성된 지 24초 된 캐시 엔트리가 사라지는 것도 관측됐다. 같은 시그니처가 독립 계정 3곳에서 확인됐다.
개인 환경 문제인지 광범위한 문제인지 가르려면 여러 기계에서 모은 구조화된 데이터가 필요하다. 그것을 모으는 곳이 이 사이트다. 논의는 anthropics/claude-code#87966에서 진행 중이다.
내 로그로 진단을 돌리면 돌아오는 화면이 이 모양이다. 아래 테두리 안의 숫자는 지어낸 값이 아니라 운영자 기계 1대의 실측이다(기간은 데이터 파일이 말한다). fleet 집계가 아니라 한 대짜리라서 테두리를 둘렀다. 창은 아래 fleet 행과 같은 전체 기간이다. 숫자가 몇 건 어긋나 보인다면 두 스냅샷의 스캔 시각 차이다. 이 파일을 만든 뒤에 생긴 유실은 다음 제출 때 fleet 행에 합류한다. 만든 방법은 scripts/build_preview.js에 있고, 결과 파일은 assets/preview.js다.
시간대가 왜 여기만 보이나: 제출 스키마에는 일별 집계만 있고 시간대 항목이 아예 없다. 제출만으로 언제 일하는지가 드러나지 않도록 일부러 뺐고, 그 결정은 그대로다. 이 화면의 시간대는 운영자가 자기 기계 것을 스스로 공개한 것이지 누구에게서 걷은 값이 아니다. 제출하는 사람의 시간대는 애초에 수집되지 않는다. requestId와 로그 파일 경로는 이 파일에 없다. 생성기가 그 둘이 들어간 파일은 쓰지 않고 중단한다.
내 로그로 직접 돌려보기 → 파싱은 브라우저 안에서 일어난다. 로그 파일은 기기를 떠나지 않고, 공유 버튼을 누르기 전에는 아무것도 제출되지 않는다.
그날 요청 대비 집계 유실 비율을 보고한 기계 전체를 하나로 합쳐 한 선으로 그린다. 선이 올라간다는 건 제출자가 늘었다는 뜻이 아니라 보낸 요청 중 잃은 비율이 커졌다는 뜻이다. 분모가 같은 날의 요청 수이기 때문이다. 유지되는 하락 계단은 수정 배포 시점을 가리킨다. 이 축의 하루는 모두 UTC 기준이고 모든 제출에 같은 기준이 적용된다. 서로 다른 기계를 같은 날짜에 합산하는 일이 의미를 가지는 근거가 이것이다. 한 대만 보고한 날은 그 한 대의 유실률이다. 그래서 그날 몇 대가 보고했는지도 함께 그린다. 날짜마다 기계 수가 달라지면 각 날짜 뒤에 옅은 세로 막대로 나타나고, 모든 날이 같은 수인 동안에는 범례가 그 수를 글로 적는다.
기계마다 한 선씩 그리는 게 이전 설계였다. 제출 1건일 때는 읽히지만 50건이면 읽을 수 없고, 방문자마다 모든 제출자의 일별 이력 전체를 내려받게 만든다. 기계별 숫자가 사라진 건 아니다. 제출 목록의 각 행이 그 행의 합계가 곧 그 합인 파일을 링크한다.
시간대 공개를 스스로 켠 기계만 반영한다(진단 페이지의 체크박스, 기본 끔). 칸마다 몇 대의 기계가 실려 있는지가 다르므로 각 칸 툴팁에 그 수를 함께 적는다. 1대짜리 칸은 그 1대의 기록이다. 모든 칸은 UTC 시간이다.
아직 시간대별 공개를 켠 기계가 없다. 진단 페이지의 "시간대별도 함께 공개"를 켜고 제출하면 여기부터 채워진다.
같은 제출 데이터를 환경 항목 하나로 묶어 본 것이다. 표본 수는 모든 행에 함께 적는다. 기준 미만인 그룹은 건수만 보여주고 유실률은 내지 않는다.
제출 데이터를 어떤 자기신고 항목으로 묶을지 고르는 버튼이다. 고른 기준으로 아래 표가 다시 묶이고, 그룹마다 유실률을 새로 계산하며, 표본 수는 모든 행에 함께 적는다.
이 테두리 안의 숫자는 단 하나도 관측이 아니다. 이 섹션이 앞으로 그릴 비교가 어떤 모양인지 보여주려고 지어낸 고정 숫자이고, 실제 표본이 하한 미만인 동안만 그 자리에 서 있다. 이 페이지에서 실제 데이터에는 언제나 녹색 실제 제출 데이터 배지가 붙는다. fleet 차트, 제출 목록, 그리고 행이 충분히 모인 뒤의 이 비교표가 그것이다.
| 값 (예시) | 표본 수 (n) | 합산 요청 | 유실 | 유실률 |
|---|
| 값 | 표본 수 (n) | 합산 요청 | 유실 | 유실률 |
|---|
| 닉네임 | 클라이언트 | 플랜 | 동시 세션 | 총 요청 | 유실 | 유실률 |
|---|
이 페이지의 모든 수치는 문자열 하나에서 나온다. 서버가 직접 찍는 cache_miss_reason이 previous_message_not_found일 때다. 이름에 의존한다는 뜻이고, 이름은 바뀐다. 만약 바뀌면 위의 모든 차트가 조용히 0으로 떨어지고 그게 좋은 소식처럼 읽힌다. 그래서 제출하는 기계마다 자기 로그에 실제로 있던 사유값 이름도 같이 보고한다. 이름만 보내고 각각 몇 건인지는 보내지 않는다. 이 표가 그 목록이다.
| 값 | 기계 수 |
|---|
| 버전 | 기계 수 |
|---|
제출별 집계 합계. 시각·세션 ID·파일 경로는 없다. 스키마 차원에서 담을 수 없다. 닉네임은 마스킹해서 저장하므로, 본인이 제출한 행은 이 브라우저에 남은 기록으로 표시한다. 열 제목을 누르면 정렬된다. 화면에 보이는 행 순서만 바뀌고 이 페이지의 다른 것은 아무것도 바뀌지 않는다.
마지막 열은 그 행의 일별 원본 파일을 링크한다. 행의 합계가 곧 그 파일의 합이므로 산수를 한 행씩 따로 검증할 수 있다. 색인(이 표), 일자별 시계열(위 그래프), 그리고 기계당 상세 파일 1개다. 이 페이지가 내려받는 건 앞의 둘뿐이고 상세 파일은 절대 자동으로 받지 않는다. 여는 건 읽는 사람의 선택이다. 지문 파일도 마찬가지다. 공개돼 있고 여기서 링크하지만 받지는 않는다.
| 일별 원본 |
|---|
무엇을 유실로 판정하는지, 그리고 왜 모든 단계를 직접 검증할 수 있는지.
이 페이지는 아무것도 남기지 않는다. 진단 페이지는 기본값으로 남긴다. 거기서 스캔이 끝나면 총계·일별 집계·시간대별 요청 수가, 이 기계를 한 행으로 유지하는 지문 해시와 함께 그 브라우저의 저장 공간에 기록된다. 그 페이지의 체크박스로 끌 수 있고(스캔 전이든 후든), 최근 8건까지만 남는다.
저장분의 성격: 그 컴퓨터의 그 브라우저 안에만 있고, 서버로는 전송되지 않으며, "저장된 기록 지우기"를 누르면 즉시, 완전히 삭제된다. 다음 진단이 마지막 제출 다음 날부터 시작되게 해서 이미 공유한 기간을 다시 보내지 않도록 하는 용도다. 로그 파일 경로·세션 ID·requestId·대화 내용은 저장하지 않는다. 제출 스키마에서 빼 둔 것과 같은 기준이다. 공용·공유 컴퓨터에서는 저장하지 말 것.
실행되는 코드가 repo 파일 그대로다(빌드 없음). 브라우저 view-source와 repo를 한 줄씩 대조할 수 있다. 구성은 이게 전부다: