요약: Claude API의 ITPM은 대부분의 모델에서 cached input tokens를 rate limit에 포함하지 않는다. 이 특성을 모르면 긴 시스템 프롬프트와 대형 문서를 쓰는 서비스가 불필요하게 429에 걸린다. 반대로 cache breakpoint, hit rate 관측, 요청 큐를 제대로 설계하면 같은 tier에서도 처리량을 크게 높일 수 있다.
LLM 서비스 운영자가 처음 보는 지표는 보통 RPM이다. 분당 요청 수가 몇 개인지, worker를 몇 개 띄울지, queue depth가 어느 정도인지부터 계산한다. 하지만 Claude API처럼 input token 한도가 명확한 API에서는 RPM보다 ITPM(input tokens per minute)이 먼저 병목이 되는 경우가 많다.
예를 들어 고객지원 agent가 매 요청마다 30,000 token짜리 정책 문서, 8,000 token짜리 tool schema, 2,000 token짜리 시스템 지침을 넣는다고 하자. 사용자 질문은 100 tokens뿐이어도 uncached input이 40,100 tokens라면 Start tier의 2,000,000 ITPM 기준 이론상 분당 49건 정도에서 막힌다. RPM 1,000은 남아 있지만 아무 의미가 없다.
이때 prompt caching을 제대로 쓰면 계산이 달라진다. Anthropic 문서 기준 대부분의 Claude 모델에서 cache_read_input_tokens는 ITPM rate limit에 포함되지 않는다. 긴 정책 문서와 tool schema가 cache hit로 읽히면 rate limit상 새로 들어간 토큰은 사용자 질문과 cache breakpoint 이후 변경분 중심이 된다.
Claude API 사용량에는 input_tokens, cache_creation_input_tokens, cache_read_input_tokens 같은 값이 나온다. 문서 설명에 따르면 input_tokens는 전체 입력이 아니라 마지막 cache breakpoint 이후의 토큰을 나타낸다. total input tokens는 cache_read_input_tokens + cache_creation_input_tokens + input_tokens로 계산해야 한다.
Rate limit 관점에서는 대부분의 모델에서 input_tokens와 cache_creation_input_tokens가 ITPM에 잡히고, cache_read_input_tokens는 잡히지 않는다. 단, Haiku 3.5처럼 예외가 있을 수 있으므로 모델별 표시를 확인해야 한다.
이 차이는 크다. 200,000 token 문서가 캐시되어 있고 사용자 질문이 50 tokens라면 total input은 200,050 tokens다. 하지만 rate limit상 새로 소비하는 ITPM은 훨씬 작을 수 있다. Anthropic은 2,000,000 ITPM limit에서 cache hit rate 80%라면 실제로 10,000,000 total input tokens per minute을 처리할 수 있는 예시를 든다.
캐시 후보는 반복되고, 크고, 자주 바뀌지 않는 입력이다. 시스템 프롬프트, agent policy, tool definitions, 대형 context document, 제품 매뉴얼, 반복되는 conversation prefix가 대표적이다. 반대로 사용자별 최신 상태, 권한에 따라 달라지는 데이터, 짧고 매번 바뀌는 질의는 캐시 이득이 작거나 위험하다.
좋은 구조는 prompt를 stable prefix와 volatile suffix로 나누는 것이다. stable prefix에는 정책, 역할, 출력 형식, tool schema, 공통 문서를 둔다. volatile suffix에는 사용자 질문, 현재 화면 상태, 방금 검색한 결과, request-specific constraints를 둔다. cache breakpoint는 stable prefix가 끝나는 지점에 둔다.
주의할 점은 작은 변경이 prefix 전체를 깨뜨릴 수 있다는 것이다. 날짜, request id, 사용자 이름 같은 값을 stable prefix 앞쪽에 넣으면 매 요청마다 캐시가 miss된다. 이런 값은 뒤쪽 suffix로 밀어야 한다. prompt template을 관리할 때도 공백, 순서, tool schema serialization이 안정적으로 유지되도록 해야 한다.
Start tier에서 Sonnet 4.x를 쓴다고 가정하자. 문서 기준 Start tier의 Sonnet 4.x는 1,000 RPM, 2,000,000 ITPM, 400,000 OTPM이다. 요청당 total input은 50,000 tokens, output은 1,000 tokens다. 캐시가 없으면 ITPM 기준 분당 40건, OTPM 기준 분당 400건, RPM 기준 분당 1,000건이므로 병목은 ITPM 40건이다.
이제 50,000 tokens 중 45,000 tokens가 cache read이고, 새 input이 5,000 tokens라고 하자. ITPM 기준 분당 400건까지 올라간다. output 1,000 tokens라면 OTPM도 분당 400건이므로 병목이 ITPM에서 OTPM과 같아진다. 같은 tier, 같은 모델, 같은 total input인데 cache hit 덕분에 처리량이 10배 차이 난다.
이 계산은 실제 운영에서 바로 써야 한다. endpoint별로 p50, p95 input tokens, cache creation, cache read, output tokens를 수집하고, concurrency limit을 가장 낮은 병목 기준으로 잡는다. 평균만 보면 안 된다. p95 요청이 긴 문서를 새로 캐시하는 순간 ITPM을 크게 잡아먹을 수 있다.
Claude API는 token bucket 방식으로 rate limit을 적용한다. capacity는 고정 interval에 한 번 리셋되는 것이 아니라 계속 보충된다. 따라서 모든 worker가 같은 초에 요청을 몰아넣으면 짧은 burst로 429가 발생할 수 있다. 또한 급격한 트래픽 증가는 acceleration limit에 걸릴 수 있다.
큐는 token-aware해야 한다. 요청이 들어올 때 예상 uncached input과 예상 output을 계산하고, 현재 minute budget에 맞춰 실행한다. 정확한 output은 실행 전 알 수 없으므로 endpoint별 historical p90 값을 잡는다. 429가 오면 retry-after header를 따르고, 같은 요청을 여러 worker가 중복 재시도하지 않도록 lease를 둔다.
캐시 생성 요청도 조심해야 한다. 새 문서가 들어오는 첫 요청은 cache_creation_input_tokens로 ITPM을 사용한다. 많은 사용자가 같은 새 문서를 동시에 처음 호출하면 캐시 생성 폭주가 생긴다. 인기 문서나 공통 tool schema는 사전 warm-up 요청으로 캐시를 만들어두는 전략이 유효하다.
input_tokens, cache_creation_input_tokens, cache_read_input_tokens, output tokens를 모두 저장한다.retry-after를 따르고, token bucket 특성에 맞춰 burst를 완화한다.