Claude Code 비용의 90%를 결정하는 한 가지, 프롬프트 캐싱

Claude Code를 본격적으로 쓰기 시작하면 가장 먼저 신경 쓰이는 게 비용이다. API 과금 구조를 살펴보면 입력 토큰 비용이 대부분을 차지하는데, 여기서 프롬프트 캐싱이 제대로 작동하느냐 아니냐에 따라 같은 작업을 하고도 비용이 10배까지 차이 난다. 과장이 아니라 실제 가격 구조가 그렇다. Claude Sonnet 기준으로 일반 입력 토큰은 백만 토큰당 3달러인데, 캐시에서 읽어오는 토큰은 0.3달러다. 정확히 10분의 1이다.
2026년 2월, Claude Code 개발팀의 Thariq Shihipar가 "Lessons from Building Claude Code: Prompt Caching Is Everything"이라는 글을 공개했다. Claude Code를 만들면서 깨달은 프롬프트 캐싱 최적화 노하우를 정리한 글인데, 에이전트를 만드는 개발자뿐 아니라 Claude Code 사용자에게도 비용 줄이는 법이 담겨 있다. Thariq는 이렇게 말했다.
"Claude Code에서 작업하면서 얻은 가장 큰 깨달음은, 에이전트를 설계할 때 프롬프트 캐싱을 가장 먼저 고려해야 한다는 것입니다. 거의 모든 기능이 캐싱과 연결되어 있습니다."
Thariq의 글을 바탕으로, 프롬프트 캐싱이 어떻게 돌아가고 비용을 어떻게 줄일 수 있는지 정리해본다.
프롬프트 캐싱이 뭔데, 왜 이렇게 중요한가
프롬프트 캐싱을 이해하려면 먼저 Claude Code가 API와 어떻게 대화하는지 알아야 한다. Claude Code에서 한 번의 요청을 보낼 때, 실제로 API에 전달되는 데이터는 다음과 같은 순서로 구성된다.
- 도구 정의 (tools): Claude Code가 사용할 수 있는 모든 도구의 목록과 스키마
- 시스템 프롬프트 (system): Claude Code의 동작 규칙, CLAUDE.md 내용 등
- 대화 메시지 (messages): 지금까지 주고받은 모든 대화 내용
매번 요청할 때마다 이 전체가 API로 전송된다. 대화가 10턴째라면 이전 9턴의 대화 내용이 모두 포함된다. 대화가 길어질수록 입력 토큰이 빠르게 불어난다. 100K 토큰 컨텍스트가 있는 세션에서 20턴을 대화하면, 캐싱 없이는 매 턴마다 100K+ 토큰에 대한 비용을 전부 내야 한다.
프롬프트 캐싱이 여기서 등장한다. 이전 요청과 동일한 접두사 부분을 캐시에 저장해두고, 다음 요청에서 그 부분을 재사용하는 방식이다. 10번째 턴에서 새로 추가된 메시지만 비싼 입력 토큰 가격을 내고, 나머지 9턴의 대화 내용은 캐시 히트 가격인 10분의 1로 처리된다.
Anthropic 공식 문서에 나와 있는 가격표를 정리하면 이렇다.
| 모델 | 일반 입력 | 캐시 쓰기(5분) | 캐시 읽기(히트) | 절감률 |
|---|---|---|---|---|
| Claude Sonnet 4.6 | $3/MTok | $3.75/MTok | $0.30/MTok | 90% |
| Claude Opus 4.6 | $5/MTok | $6.25/MTok | $0.50/MTok | 90% |
| Claude Haiku 4.5 | $1/MTok | $1.25/MTok | $0.10/MTok | 90% |
캐시 쓰기는 일반 입력 대비 1.25배를 내야 하지만, 캐시 읽기는 0.1배다. 처음 한 번만 조금 더 내고 이후에는 10분의 1만 내는 구조다. DEV Community의 kitaekatt이 분석한 실제 시뮬레이션을 보면, 100K 토큰의 안정적인 컨텍스트가 있는 20턴 세션에서 캐싱 없이는 6달러, 캐싱이 적용되면 1달러 내외로 줄었다. 80% 이상의 비용 절감이다.
여기서 핵심은 "접두사 매칭"이라는 작동 방식이다. 캐시는 요청의 처음부터 특정 지점까지 연속된 동일한 내용을 기준으로 작동한다. 중간이나 끝부분만 같아서는 캐시 히트가 발생하지 않는다. 또한 캐시가 생성되려면 최소한의 접두사 길이가 필요하다. Claude Sonnet과 Opus는 1024 토큰, Haiku는 2048 토큰 이상의 접두사가 있어야 캐시가 만들어진다. Claude Code는 도구 정의와 시스템 프롬프트만으로도 이 조건을 충족하므로 일반 사용에서는 걱정할 필요 없지만, 직접 API를 사용하는 개발자라면 이 임계값을 알아두어야 한다. tools, system, messages 순서로 쌓이는 접두사에서 어느 한 부분이라도 바뀌면 그 이후의 모든 캐시가 무효화된다.
그래서 Claude Code 팀은 캐시 적중률을 시스템 가동시간처럼 모니터링한다. 적중률이 떨어지면 SEV(심각도 사건)로 선언할 정도다. 캐시 미스율이 몇 퍼센트만 올라가도 비용과 응답 시간에 바로 영향을 미치고, 구독 플랜에서 관대한 레이트 리밋을 유지할 수 있는 것도 높은 캐시 적중률이 받쳐주기 때문이다.
Thariq의 5가지 교훈, 개발자가 아니라도 알아야 할 것
Thariq가 정리한 5가지 교훈을 하나씩 살펴보자. 에이전트 개발자를 위한 내용도 있지만, 여기서는 Claude Code 사용자 입장에서 중요한 부분을 추려서 정리한다.
교훈 1. 접두사 매칭의 원리를 이해하라
프롬프트 캐싱은 "정적 콘텐츠 먼저, 동적 콘텐츠 마지막"이라는 원칙 위에서 작동한다. Claude Code의 요청 구조를 보면 이 원칙이 어떻게 적용되는지 보인다.
[도구 정의] ← 거의 변하지 않음 (전역 캐시) [시스템 프롬프트] ← 세션 내에서 거의 고정 [CLAUDE.md] ← 프로젝트별 고정 [세션 컨텍스트] ← 세션 내에서 점진적 증가 [새 대화 메시지] ← 매 턴마다 변경
가장 안 바뀌는 것이 맨 위에, 가장 자주 바뀌는 것이 맨 아래에 놓인다. 이렇게 하면 대부분의 요청에서 상위 부분은 캐시 히트가 되고, 하단의 새 메시지만 비싼 입력 토큰으로 처리된다.
다음 그림은 이 접두사 매칭 구조를 시각적으로 정리한 것이다.

도구 정의부터 시스템 프롬프트, CLAUDE.md, 세션 컨텍스트까지 위에서부터 안정적인 순서로 쌓이고, 이 영역이 캐시 히트 대상이 된다. 매 턴마다 실제로 비싼 입력 토큰으로 처리되는 건 맨 아래의 새 대화 메시지뿐이다.
이 원리를 Claude Code 사용자가 이해해야 하는 이유는 간단하다. 이 순서를 깨뜨리는 행동을 하면 캐시가 통째로 무효화되기 때문이다. 예를 들어 도구 정의가 바뀌면 그 아래의 시스템 프롬프트, CLAUDE.md, 대화 메시지 캐시가 모두 날아간다.
Anthropic 공식 문서에서는 캐시 무효화 계층을 이렇게 설명한다.
| 변경 사항 | 도구 캐시 | 시스템 캐시 | 메시지 캐시 |
|---|---|---|---|
| 도구 정의 변경 | 무효화 | 무효화 | 무효화 |
| 웹 검색 토글 | 유지 | 무효화 | 무효화 |
| 속도 설정 변경 | 유지 | 무효화 | 무효화 |
| 이미지 추가/제거 | 유지 | 유지 | 무효화 |
도구 정의 변경이 가장 파괴적이다. 모든 레벨의 캐시를 한 번에 날린다. 시스템 프롬프트 변경은 그 아래 두 레벨을, 메시지 변경은 메시지 레벨에만 영향을 준다.
교훈 2. 시스템 프롬프트를 건드리지 마라
시스템 프롬프트는 캐시 계층의 상위에 위치한다. 여기를 변경하면 그 아래의 모든 캐시가 무효화된다. Thariq는 이를 피하기 위해 Claude Code에서 날짜 같은 동적 정보를 시스템 프롬프트에 넣지 않고, 대화 메시지의 시스템 리마인더로 주입하는 방식을 사용한다고 설명했다.
실제로 Claude Code의 최근 업데이트 내역을 보면 "날짜를 시스템 프롬프트에서 제거하여 캐시 히트율 향상"이라는 항목이 있다. 날짜 하나가 시스템 프롬프트에 있었을 뿐인데, 자정이 넘으면 시스템 프롬프트가 바뀌면서 전체 캐시가 무효화되었던 것이다. 날짜를 시스템 프롬프트가 아닌 메시지로 옮기는 것만으로 이 문제가 해결되었다.
사용자 입장에서 이게 의미하는 바는, CLAUDE.md 파일을 세션 중간에 수정하면 캐시에 영향을 줄 수 있다는 것이다. CLAUDE.md는 시스템 프롬프트의 일부로 들어가기 때문이다. 세션 시작 전에 CLAUDE.md를 완성해두고, 세션 중에는 건드리지 않는 편이 낫다.
교훈 3. 세션 중에 모델과 도구를 바꾸지 마라
Thariq의 5가지 교훈 중 Claude Code 사용자에게 가장 와닿는 교훈이다. 사용자가 직접 제어할 수 있으면서도 비용 차이가 가장 크게 벌어지는 부분이기 때문이다.
세션 중에 /model 명령으로 모델을 바꾸면 어떻게 될까. 프롬프트 캐시는 모델별로 격리되어 있다. Sonnet으로 대화하다가 Opus로 바꾸면, Sonnet 세션에서 쌓아둔 캐시를 Opus가 읽을 수 없다. 캐시가 0%에서 다시 시작된다. 100K 토큰 규모의 컨텍스트였다면, 그 전체를 다시 캐시에 쓰기 위해 1.25배의 비용을 내야 한다.
도구 설정도 마찬가지다. 웹 검색을 켜거나 끄면 시스템 프롬프트가 변경되면서 캐시가 무효화된다. 확장 사고(extended thinking) 설정을 바꿔도 같은 일이 벌어진다. /fast 모드를 토글하면 속도 설정이 바뀌면서 시스템 캐시와 메시지 캐시가 모두 날아간다.
Claude Code 팀은 이 문제를 어떻게 해결했을까. 도구 세트를 세션 중에 추가하거나 제거하는 대신, 모든 도구를 항상 요청에 포함시키고 EnterPlanMode, ExitPlanMode 같은 "상태 전환 도구"를 통해 모드를 관리한다. 도구를 빼는 대신 도구 로딩을 지연시키는 방식이다.
현업 개발자에게 들어보니, 가장 흔한 실수가 "Sonnet으로 코드 짜다가 리뷰할 때만 Opus로 바꾸기"라고 한다. 의도는 좋지만 캐시 관점에서는 최악이다. 모델을 바꿀 때마다 캐시가 리셋되므로, 차라리 한 모델로 끝까지 작업하고 리뷰는 별도 세션에서 하는 것이 비용 면에서 훨씬 낫다.
세션 중에 피해야 할 변경을 정리하면 이렇다. 앞서 정리한 무효화 계층 표와 대응시켜 보면 근거가 명확하다.
- 모델 전환 (
/model): 캐시는 모델별로 격리되므로 전체 캐시가 리셋된다. 이전 모델에서 쌓은 캐시를 새 모델이 읽을 수 없다. - 웹 검색 토글: 무효화 계층 표의 "웹 검색 토글" 항목에 해당한다. 시스템 프롬프트가 변경되면서 시스템 캐시와 메시지 캐시가 모두 무효화된다.
- 확장 사고 토글: 요청 파라미터가 변경되면서 메시지 캐시에 영향을 줄 수 있다.
- 빠른 모드 전환 (
/fast): 무효화 계층 표의 "속도 설정 변경"에 해당한다. 시스템 캐시와 메시지 캐시가 무효화된다.
교훈 4. 캐시 적중률을 모니터링하라
Thariq는 Claude Code 팀이 캐시 적중률을 시스템 가동시간처럼 모니터링한다고 밝혔다. 적중률이 떨어지면 경보가 울리고, 심각하면 SEV로 선언하고 즉시 대응한다. 개인 사용자가 이 정도까지 할 필요는 없지만, 내 캐시 적중률이 얼마인지 정도는 파악하고 있어야 한다.
세션에서 처음 대화를 시작하면 캐시에 저장된 내용이 없으므로 캐시 히트율은 0%에서 시작한다. 첫 번째 요청이 처리되면 시스템 프롬프트와 도구 정의가 캐시에 쓰여지고, 두 번째 요청부터는 그 부분이 캐시 히트가 된다. 대화가 진행될수록 캐시된 토큰의 비율이 올라가면서 히트율이 100%에 가까워진다. 중요한 건 이 비율이 떨어지지 않게 유지하는 것이다.
캐시 적중률을 확인하는 방법은 여러 가지가 있다. Claude Code의 상태 라인에서 current_usage 객체가 제공하는 cache_read_input_tokens와 cache_creation_input_tokens 값을 활용하면 된다.
캐시 히트율 = cache_read_input_tokens / 총 입력 토큰 * 100 총 입력 토큰 = cache_read_input_tokens + cache_creation_input_tokens + input_tokens
활성 세션에서 권장되는 캐시 히트율은 약 90%다. 이 수치 아래로 떨어진다면 무언가가 캐시를 깨뜨리고 있다는 신호다.
교훈 5. 포크 작업은 부모의 접두사를 공유하라
이 교훈은 에이전트 개발자에게 더 직접적으로 해당되지만, Claude Code 사용자도 --fork-session 기능을 쓸 때 알아두면 좋다.
Claude Code에서 컴팩션이나 요약, 서브에이전트 실행 같은 사이드 연산을 수행할 때, 부모 대화와 동일한 시스템 프롬프트와 도구 정의를 사용해야 캐시를 공유할 수 있다. --fork-session으로 병렬 작업을 생성하면 기본 세션의 캐시를 여러 포크가 재사용한다. 이것이 가능한 이유는 도구 정의와 시스템 프롬프트라는 접두사가 동일하기 때문이다.
반대로, 포크 세션에서 모델이나 도구 설정을 다르게 가져가면 부모의 캐시를 공유할 수 없다. 병렬 작업을 할 때도 캐시 접두사를 맞추는 게 비용 면에서 중요하다.
실전 비용 최적화 전략
Thariq의 교훈을 바탕으로, Claude Code를 실제로 사용할 때 적용할 수 있는 구체적인 전략을 정리한다.
전략 1. 한 세션에서 최대한 많이 하라
같은 파일을 다루는 작업이라면 여러 세션으로 나누지 말고 한 세션에서 처리하는 것이 훨씬 효율적이다.
kitaekatt의 분석에 따르면, 100K 토큰짜리 파일을 5개의 별도 세션에서 각각 로드하면 총 비용이 6.25배가 된다. 같은 파일을 한 세션에서 5번 참조하면 1.65배로 끝난다. 약 3.8배의 차이다. 이유는 간단하다. 각 세션마다 캐시를 새로 쌓아야 하기 때문이다.
실전에서 이 원칙을 적용하면 이렇게 된다. "이 파일의 버그를 고쳐줘"라고 요청한 뒤, 고친 다음에 "이 파일의 테스트도 짜줘"를 같은 세션에서 하면 파일 내용이 이미 캐시에 있어서 저렴하게 처리된다. 하지만 버그 수정 후 /clear를 하고 새 세션에서 테스트를 요청하면 파일을 다시 읽고 캐시를 다시 쌓아야 한다.
전략 2. /clear와 /compact를 구분하라
/clear와 /compact는 비슷해 보이지만 캐시에 미치는 영향이 완전히 다르다.
/clear는 대화 히스토리를 완전히 초기화한다. CLAUDE.md는 다시 읽지만, 캐시는 0%에서 재시작된다. 관련 없는 작업 사이에서 컨텍스트를 정리할 때 적합하다.
/compact는 대화를 요약하여 컨텍스트를 줄인다. 핵심 결정사항과 코드 패턴은 보존하면서 불필요한 대화를 제거한다. 캐시 관점에서는 /clear보다 유리하다. 요약된 내용이 이전 접두사의 일부를 유지할 수 있기 때문이다. /compact에 지시를 추가할 수도 있다. /compact API 변경사항에 집중해줘처럼 쓰면 된다.
컨텍스트가 너무 커졌을 때는 먼저 /compact를 시도하고, 완전히 다른 주제로 넘어갈 때만 /clear를 쓰는 편이 비용 면에서 유리하다.
다만 /compact도 만능은 아니다. 대화를 요약하는 과정에서 접두사가 변경되면 캐시 미스가 발생할 수 있다. 어떤 명령을 쓰든 캐시 히트율을 보면서 판단하는 게 맞다.
전략 3. TTL을 이해하고 리듬을 유지하라
캐시에는 유효 시간(TTL)이 있다. 기본 TTL은 5분이다. Max 플랜 사용자는 1시간 TTL을 사용할 수 있다.
5분 TTL의 의미는, 마지막 캐시 히트로부터 5분 동안 아무 요청이 없으면 캐시가 만료된다는 것이다. 중요한 점은, 캐시된 콘텐츠가 사용될 때마다 TTL이 갱신된다는 것이다. 추가 비용 없이 계속 대화를 이어가면 캐시가 영원히 살아 있다. 하지만 5분 이상 자리를 비우면 캐시가 만료되고, 다음 요청에서 전체를 다시 캐시에 써야 한다.
실무에서 이런 상황이 자주 발생한다. 코드를 검토하다가 커피를 마시러 가고, 돌아와서 다시 질문하면 캐시가 날아가 있다. 100K 토큰짜리 컨텍스트였다면 캐시 쓰기 비용만으로 Sonnet 기준 $0.375가 추가된다. 자주 반복되면 무시할 수 없는 금액이다.
대응 방법은 두 가지다. Max 플랜이라면 1시간 TTL을 활용하는 것이 가장 편하다. 다만 1시간 TTL의 캐시 쓰기 비용은 기본 입력의 2배이므로, 세션이 짧다면 오히려 손해일 수 있다. Pro 플랜이라면 작업 중에 5분 이상 쉬지 않는 리듬을 유지하거나, 긴 휴식 전에 작업 내용을 정리해두고 돌아와서 필요한 파일만 다시 참조하는 방법이 있다.
전략 4. 세션 전략을 상황에 맞게 설계하라
캐시 관점에서 세션 전략을 정리하면 이렇다.
한 세션을 유지해야 할 때. 같은 파일군을 대상으로 연속 작업할 때다. 버그 수정 후 테스트 작성, 리팩토링 후 문서 업데이트 같은 흐름이 여기에 해당한다. 컨텍스트가 겹치는 작업은 한 세션에서 이어가야 캐시를 제대로 활용할 수 있다.
세션을 나눠야 할 때. 완전히 다른 프로젝트나 파일군으로 넘어갈 때다. 이전 세션의 컨텍스트가 오히려 방해가 되고, 새 작업에 필요한 파일을 캐시에 올리는 것이 더 효율적이다.
포크를 사용해야 할 때. 동일한 코드베이스에서 독립적인 병렬 작업을 할 때다. --fork-session을 쓰면 부모 세션의 캐시를 공유하면서 각자의 작업을 진행할 수 있다. 이때 포크 세션에서 모델이나 도구 설정을 바꾸지 않는 것이 중요하다.
캐시 히트율 모니터링 실전 가이드
일단 측정부터 해야 한다. 지금 캐시 히트율이 얼마인지 모르면 뭘 고칠 수도 없다.
상태 라인으로 실시간 모니터링
Claude Code의 상태 라인은 커스터마이징이 가능하다. ~/.claude/settings.json에 설정을 추가하면 된다.
{ "statusLine": { "type": "command", "command": "~/.claude/statusline.sh" } }
상태 라인 스크립트에 캐시 히트율을 표시하려면, Claude Code가 stdin으로 전달하는 JSON 데이터에서 context_window.current_usage 객체를 파싱하면 된다. 이 객체에는 다음 필드가 포함된다.
input_tokens: 캐시되지 않은 입력 토큰output_tokens: 출력 토큰cache_creation_input_tokens: 캐시에 새로 쓰인 토큰cache_read_input_tokens: 캐시에서 읽어온 토큰
캐시 히트율을 포함하는 상태 라인 스크립트 예시다. 이 스크립트는 jq가 필요하다. macOS에서는 brew install jq, Linux에서는 apt install jq로 설치할 수 있다.
#!/bin/bash input=$(cat) MODEL=$(echo "$input" | jq -r '.model.display_name') COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0') PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1) # 캐시 히트율 계산 CACHE_READ=$(echo "$input" | jq -r '.context_window.current_usage.cache_read_input_tokens // 0') CACHE_WRITE=$(echo "$input" | jq -r '.context_window.current_usage.cache_creation_input_tokens // 0') INPUT=$(echo "$input" | jq -r '.context_window.current_usage.input_tokens // 0') TOTAL=$((CACHE_READ + CACHE_WRITE + INPUT)) if [ "$TOTAL" -gt 0 ]; then CACHE_HIT=$((CACHE_READ * 100 / TOTAL)) else CACHE_HIT=0 fi # 캐시 히트율에 따른 색상 if [ "$CACHE_HIT" -ge 80 ]; then CACHE_COLOR='\033[32m' # 녹색 elif [ "$CACHE_HIT" -ge 50 ]; then CACHE_COLOR='\033[33m' # 노란색 else CACHE_COLOR='\033[31m' # 빨간색 fi RESET='\033[0m' COST_FMT=$(printf '$%.4f' "$COST") printf "[%s] %s%% ctx | %bCache %s%%%b | %s\n" "$MODEL" "$PCT" "$CACHE_COLOR" "$CACHE_HIT" "$RESET" "$COST_FMT"
이 스크립트를 ~/.claude/statusline.sh로 저장하고 실행 권한을 주면(chmod +x), 매 응답 후 하단에 모델명, 컨텍스트 사용율, 캐시 히트율, 세션 비용이 표시된다. 캐시 히트율이 80% 이상이면 녹색, 50~79%면 노란색, 50% 미만이면 빨간색으로 표시되어 한눈에 상태를 파악할 수 있다.
claude-dashboard 플러그인
직접 스크립트를 작성하기 번거롭다면, claude-dashboard 플러그인이 정보를 균형 있게 잘 보여준다. 컨텍스트 사용량, API 레이트 리밋, 비용 추적에 더해 캐시 히트율까지 직관적으로 보여준다. compact(1줄), normal(2줄), detailed(3줄), custom 모드를 지원하므로 터미널 크기에 맞게 선택할 수 있다.
디버그 로깅
더 상세한 분석이 필요하면 환경 변수를 설정해서 HTTP 요청/응답을 로깅할 수 있다.
ANTHROPIC_LOG=debug claude
이렇게 하면 매 API 호출의 상세한 토큰 사용량을 확인할 수 있다. 일상적으로 쓰기에는 지나치게 상세하지만, 캐시 문제를 디버깅할 때 유용하다.
자동 캐싱과 명시적 캐싱
기술적 배경을 하나 더 짚겠다. Anthropic API는 두 가지 캐싱 방식을 제공한다.
첫째, 자동 캐싱이다. 요청 본문의 최상위에 cache_control 필드 하나만 추가하면 시스템이 알아서 마지막 캐시 가능한 블록에 브레이크포인트를 적용한다. 대화가 길어지면 캐시 포인트가 자동으로 앞으로 이동한다. 멀티턴 대화에 최적화된 방식이다.
response = client.messages.create( model="claude-sonnet-4-6", max_tokens=1024, cache_control={"type": "ephemeral"}, # 이것만 추가하면 자동 캐싱 system="시스템 프롬프트 내용", messages=[...], )
둘째, 명시적 캐시 브레이크포인트다. 개별 콘텐츠 블록에 cache_control을 직접 지정하여 캐시 지점을 세밀하게 제어한다. 최대 4개의 브레이크포인트를 설정할 수 있다.
Claude Code는 내부적으로 이 두 가지를 조합하여 사용한다. 직접 API를 다루지 않더라도, 이 구조를 알면 왜 특정 행동이 캐시를 깨뜨리는지 이해가 빠르다.
한 가지 더 알아둘 것은 20블록 룩백 윈도우다. 여기서 "블록"이란 API 요청 내의 개별 콘텐츠 블록을 말한다. 사용자 메시지 하나, 어시스턴트 응답 하나가 모두 개별 블록이다. 시스템은 명시적 캐시 브레이크포인트에서 역방향으로 최대 20블록까지만 검사하여 캐시 히트 여부를 판단한다.
실전에서 이것이 문제가 되는 경우를 생각해보자. 50턴 이상의 긴 대화에서 초반에 읽은 파일 내용이 20블록 바깥으로 밀려나면, 해당 부분에 대한 캐시 히트가 발생하지 않아 비용이 증가할 수 있다. 이런 상황이 의심된다면 /compact로 대화를 압축하면 블록 수가 줄어들어 캐시 효율이 회복된다. 대화가 매우 길어졌을 때 캐시 효율이 떨어지는 이유 중 하나가 바로 이 룩백 윈도우 제한이다.
비용 시뮬레이션으로 체감하기
숫자로 직접 비교해보면 감이 온다.

캐싱 없이 매 턴마다 전체 토큰에 정가를 내면 $6.00, 캐싱이 적용되면 $1.00으로 83%의 비용 차이가 발생한다. 이 시뮬레이션의 구체적인 계산 과정을 살펴보자.
Claude Sonnet 4.6 기준으로, 100K 토큰의 시스템 프롬프트와 대화 히스토리가 있는 세션에서 20턴의 대화를 한다고 가정하자.
캐싱 없이 매번 전체 처리하는 경우.
매 턴마다 약 100K 토큰 x $3/MTok = $0.30의 입력 비용이 발생한다. 20턴이면 $6.00이다.
캐싱이 정상적으로 작동하는 경우.
첫 번째 턴에서 100K 토큰을 캐시에 쓴다. $3.75/MTok x 0.1M = $0.375다. 이후 19턴에서는 캐시 히트로 처리된다. $0.30/MTok x 0.1M x 19 = $0.57이다. 캐시 쓰기와 캐시 읽기만 합산하면 $0.945다. 여기에 매 턴의 새 메시지 토큰(약 1K)을 더하면 약 $1.0 수준이 된다.
$6.00 대 $1.0. 캐싱만으로 83% 이상의 비용을 절감할 수 있다.
이번에는 세션 중간에 모델을 한 번 바꾸는 경우를 생각해보자. 10턴째에서 Sonnet에서 Opus로 전환한다. Sonnet 10턴의 비용은 약 $0.47이다. 하지만 Opus로 바꾸는 순간 캐시가 리셋되어 100K 토큰을 Opus 가격으로 다시 캐시에 써야 한다. Opus의 캐시 쓰기 비용은 $6.25/MTok이므로, 캐시 재구축에만 $0.625가 든다. 이후 10턴의 Opus 비용까지 합하면 전체 비용이 크게 뛴다.
모델 전환 한 번이 만드는 비용 차이가 이 정도다.
마무리
프롬프트 캐싱은 Claude Code 비용 구조에서 가장 큰 변수다. 캐시 적중률에 따라 비용이 10배까지 차이 나는 구조에서, 이걸 모르고 쓰는 것과 알고 쓰는 것은 전혀 다른 경험이다.
결국 지켜야 할 건 단순하다. 세션 중에 모델과 도구 설정을 바꾸지 않는 것, 캐시 히트율을 모니터링하는 것, 관련 작업을 한 세션에서 이어서 처리하는 것. 이것만 신경 써도 불필요한 캐시 미스는 대부분 막을 수 있다.
Thariq는 "캐시 적중률을 시스템 가동시간처럼 모니터링하라"고 했다. 상태 라인에 캐시 히트율을 띄워놓고 작업하다 보면, 어떤 행동이 캐시를 깨뜨리는지 금방 감이 온다. 그 감이 곧 돈이다.
참고 자료
- Thariq Shihipar, "Lessons from Building Claude Code: Prompt Caching Is Everything" (2026.02.19)
https://x.com/trq212/status/2024574133011673516 - Anthropic, "Prompt caching" 공식 문서
https://platform.claude.com/docs/en/build-with-claude/prompt-caching - kitaekatt, "Mastering Cache Hits in Claude Code" (DEV Community)
https://dev.to/kitaekatt/mastering-cache-hits-in-claude-code-5648 - Lance Martin, 프롬프트 자동 캐싱 관련 게시물
https://x.com/RLanceMartin/status/2024573404888911886 - Anthropic, "Best Practices for Claude Code"
https://code.claude.com/docs/en/best-practices - Claude Code Status Line 공식 문서
https://code.claude.com/docs/en/statusline - claude-dashboard 플러그인
https://github.com/uppinote20/claude-dashboard






댓글
댓글을 작성하려면 이 필요합니다.