클로드 코드 토큰 사용량 급증 원인 찾기 — Claude Code 한도 분석 도구 모니토큰(moni_token)
“별로 한 것도 없는데 왜 50분 만에 Claude 한도가 5%나 빠졌지?”
지난번 모니파드(moni_pod)가 GPU 비용을 지키는 도구였다면, 이번에 소개할 모니토큰(moni_token)은 Claude Code 토큰 사용량을 지키는 도구입니다. 실직자의 절약 시리즈 2탄이라고 해도 되겠네요.
클로드 코드 사용량이 갑자기 치솟은 날
시작은 10월 6일이었습니다. 사용량 한도가 초기화된 뒤 50분 만에 5%가 빠졌는데, 체감상 한 작업은 가벼웠어요.
원인을 Claude한테 캐물어서 겨우 알아냈습니다. 아침부터 이어 온 긴 대화 안에서 도구 호출이 34번 넘게 일어났고, 호출할 때마다 하루치 대화 전체를 다시 보낸 것으로 추정됐어요. Claude Code는 매 호출마다 지금까지의 대화(컨텍스트)를 통째로 다시 읽습니다. 프롬프트 캐시 덕분에 싸게 읽긴 하지만, 대화가 길면 “싸게 × 많이”가 꽤 큰돈이 되죠.
문제는 이걸 사람이 대화로 캐물어야만 알 수 있었다는 거예요. 그날 밤에는 작곡(RunPod)과 Mnemento 작업을 여러 세션으로 돌릴 예정이었으니, 예측 못 한 급증을 바로 알려 주고 원인을 남겨 줄 장치가 필요했습니다.
기존 도구(ccusage 등)와 뭐가 다른가
먼저 찾아봤습니다. 좋은 도구가 이미 많아요.
| 도구 | 잘하는 것 | 모니토큰이 더하는 것 |
|---|---|---|
| ccusage | 일·세션·5시간 구간별 토큰과 비용 합계 | 그 구간이 왜 비쌌는지 설명하고 사건으로 기록 |
| Claude Code Usage Monitor | 터미널 실시간 대시보드, 소모 속도, 한도 도달 예측 | 급증을 세션과 패턴에 귀속하고, 다르게 했을 때 절약량 계산 |
| ccflare | 토큰·비용·속도 차트를 보여 주는 로컬 웹 UI | 원인이 붙은 사건 목록과 호출 타임라인 |
다들 “얼마나 썼나”는 잘 보여 줍니다. 비어 있던 건 “왜 이만큼 썼나”였어요. 그래서 모니토큰은 기존 도구를 대체하려는 게 아니라, 숫자가 이상할 때 여는 도구입니다. 합계는 ccusage로 보고, 놀랄 일이 생기면 모니토큰을 보세요.
모니토큰 설계 원칙 — 토큰을 아끼는 도구가 토큰을 쓰면 안 된다
제일 먼저 정한 규칙은 이겁니다.
- LLM 호출 0회. 원인 판정은 전부 정해진 규칙(임계값·비율·순위)으로 하고, 설명 문장은 템플릿으로 만듭니다. 테스트로 “패키지가 LLM 클라이언트를 import하지 않는다”를 강제해요.
- PC 밖으로 아무것도 안 보냄. 네트워크를 안 쓰고, 대시보드는 HTML 파일 하나입니다.
- 대화 내용 저장 안 함. 토큰 수·시각·호출 수 같은 숫자와 세션 id·프로젝트 폴더 이름·모델·도구 이름 같은 메타데이터만 남깁니다.
- 로그는 읽기만. Claude Code의 파일(
~/.claude/projects/아래 jsonl)을 고치거나 지우지 않습니다. - 원인은 추정이라고 표시. 로그로 확인된 사실(호출 수, 컨텍스트 크기)과 해석(“긴 대화 × 잦은 호출”)을 구분합니다.
대시보드 — 한도 그래프와 급상승 사건

스크린샷은 합성 데모 데이터(scripts/demo_report.py)로 찍은 화면입니다.
| 영역 | 알 수 있는 것 |
|---|---|
| 맨 위 카드 | 현재 5시간·주간 한도 사용률(%), 초기화 시각, 최근 24시간 급상승 건수 |
| 절약 요약 | 이번 주에 원인별로 몇 %p를 아낄 수 있었는지와 대안 |
| 큰 덩어리 전달 | 결론 대신 원문(파일 전체, 긴 명령 출력)을 넘긴 횟수와 그 비용 |
| 한도 그래프 | 실선은 실측(Claude Code 상태줄 값), 점선은 로그로 추정한 값. 빨간 띠가 급상승 사건 |
| 급상승 사건 | 사건마다 원인. 행을 누르면 프로젝트별 점유율, 근거 수치, 호출 타임라인 |

Claude Code 토큰 사용량이 튀는 7가지 원인
모니토큰이 알아내는 원인은 이렇습니다. 사실상 “클로드 코드 토큰 아끼는 법” 목록이기도 해요.
| 원인 | 판정 근거 | 권고 |
|---|---|---|
| 긴 대화 × 잦은 호출 | 호출마다 큰 컨텍스트를 캐시에서 다시 읽고, 구간 안 호출 수가 많음 | /compact 하거나 새 세션에서 이어가기, 반복 작업은 스크립트로 |
| 공백 후 재개(캐시 만료) | 캐시 유효시간보다 오래 쉰 뒤 첫 호출이 대화 전체를 캐시에 다시 씀 | 오래 쉰 큰 세션은 이어 쓰지 말고 새 세션으로 |
| 서브에이전트·병렬 세션 | 같은 구간에 여러 세션·사이드체인이 동시에 활동 | 동시에 돌리는 수를 줄이거나 순서대로 |
| 캐시 미스 | 세션 중간에 캐시 쓰기가 급증 | 작업 중에 모델이나 설정 바꾸지 않기 |
| 큰 입력 | 이미지나 큰 파일을 읽은 직후 컨텍스트 급증 | 필요한 부분만 읽고, 원문은 파일로 넘기기 |
| 웹 조사 | WebSearch·WebFetch 호출이 많음 | 조사 범위를 좁히고 요약만 남기기 |
| 출력 폭주 | 출력 토큰 비중이 비정상적으로 큼 | 긴 결과는 파일로 쓰게 하고 출력 길이 제한 |
실제로 잡힌 사건 — 55분 동안 218번 호출
제 PC에서 실제로 잡힌 사건 하나를 보면 감이 옵니다. 9월 30일 오후, 55분 동안 5시간 한도가 15.8%p 올랐어요. 원인은 긴 대화 × 잦은 호출. 모니토큰의 설명은 이랬습니다.
구간 초입에 /compact로 컨텍스트를 약 80k로 줄였다면, 호출 218회가 각각 약 251,147토큰씩 덜 읽었을 것 (compact 후 80k 가정). → /compact 하거나 새 세션에서 이어가고, 반복 작업은 스크립트로 묶으세요.
호출 한 번에 25만 토큰을 218번 다시 읽은 거죠. 이런 문장이 규칙과 템플릿만으로, LLM 없이 만들어집니다. 제 기록에서 절약 여지가 가장 컸던 원인은 큰 입력, 긴 대화 × 잦은 호출, 공백 후 재개(캐시 만료) 순이었어요.
여기서 “절약 여지”는 “새 세션이었다면 30k”, “compact 후 80k” 같은 가정을 둔 반사실 추정입니다. 그래서 모니토큰은 로그로 확인된 사실(호출 수, 재기록 토큰)과 이런 추정을 구분해서 보여 줍니다.
한도 %를 추정하는 방법 — 상태줄 실측으로 보정
까다로운 부분이 하나 있었어요. 한도 %는 계정 단위 값이라 로컬 로그에는 없습니다. 로그에 있는 건 토큰 수뿐이에요. 그래서 모니토큰은 이렇게 합니다.
- 토큰 종류(입력·출력·캐시 쓰기·캐시 읽기)와 모델별 가중치를 정가표로 매겨 “사용량 단위”로 환산합니다.
- Claude Code 상태줄(statusLine)은 실제 한도 %를 명령에 넘겨줍니다. 모니토큰은 그 숫자만 기록해서 실측선을 그리고, 사용량 단위와 짝지어 “1% ≈ N 단위”를 자동으로 보정해요.
제 PC에서는 지금 5시간 한도 1% ≈ $3.19 상당(n=20)으로 보정돼 있습니다. 상태줄을 안 쓰면 /usage 화면의 숫자를 손으로 한 번 입력해도 추정선은 그려져요.
모니토큰 설치와 사용법
Python 3.12 이상과 uv가 필요합니다. Windows 10/11에서 개발하고 쓰고 있어요(macOS·Linux 알림 경로는 코드만 있고 미검증).
git clone https://github.com/reddol18/moni_token.git
cd moni_token
uv sync
uv run moni-token collect # 처음 한 번: 기존 로그를 ~/.moni_token/usage.db로 읽어 들임
uv run moni-token report # ~/.moni_token/report.html 생성
start $HOME\.moni_token\report.html
2분마다 자동 갱신 (작업 스케줄러)
check는 새 로그를 읽고, 새 급증이 있으면 데스크톱 알림을 띄우고, 리포트를 다시 씁니다. 1초도 안 걸려요.
$py = (Resolve-Path .venv\Scripts\pythonw.exe).Path
$action = New-ScheduledTaskAction -Execute $py -Argument "-m moni_token.cli check"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 2)
Register-ScheduledTask -TaskName "moni_token check" -Action $action -Trigger $trigger
상태줄 기록기 (실측 한도 %)
~/.claude/settings.json에 추가합니다.
"statusLine": {
"type": "command",
"command": "C:/path/to/moni_token/.venv/Scripts/moni-token-statusline.exe"
}
여기서 한 번 삽질했습니다. 경로는 꼭 슬래시(/)로 쓰세요. Windows에서 Claude Code는 이 명령을 Git Bash로 실행하는데, 역슬래시가 사라져서 C:\\path\\...로 쓰면 아무 오류 없이 그냥 안 돌아갑니다. 설정되면 상태줄에 5h 12% ~15:06 · ctx 40% 같은 표시가 뜹니다. 기존 상태줄 명령이 있다면 --wrap "<기존 명령>"으로 감싸면 돼요.
주요 명령
| 명령 | 하는 일 |
|---|---|
status |
현재 5시간 구간, 소모 속도, 구간 끝 예상치 |
events |
기록된 급증 사건과 절약 문장 |
savings |
이번 주 원인별 절약 가능량 |
analyze --from ... --to ... |
원하는 시간 구간을 골라서 원인 분석 |
chunks |
원문을 통째로 넘긴 “큰 덩어리” 목록(프로젝트별) |
급증 기준은 ~/.moni_token/config.toml에서 바꿀 수 있습니다.
[spike]
pct_jump = 3.0 # 5시간 한도가 window_min 안에 이만큼(%p) 오르면 급증
window_min = 15
realert_min = 30 # 이 시간(분) 안에는 다시 알리지 않음
single_call_cache_write_tokens = 200000 # 한 호출이 이만큼 캐시를 다시 쓰면 그 자체로 급증
내 데이터 없이 먼저 보고 싶다면 데모도 있어요.
uv run python scripts/demo_report.py demo
start demo\report.html
실제로 써 보다 잡은 버그 두 가지
직접 쓰면서 두 번 크게 데였습니다. 둘 다 커밋으로 고쳐져 있어요.
① 상태줄이 아무 오류 없이 기록을 안 했다. 위에서 말한 역슬래시 문제입니다. Windows에서 statusLine 경로를 C:\...로 쓰면 Git Bash가 역슬래시를 지워 버려서, 명령이 실행조차 안 되는데 오류도 안 납니다. 실측선이 계속 비어 있는 걸 보고서야 알았어요. 슬래시로 고치고 README에 경고를 넣었습니다.
② “한도 99% 도달” 가짜 알림. Claude Code 세션을 여러 개 켜 두면, 세션마다 상태줄로 같은 한도 %를 보내는데 일부 세션은 늦은 값을 보냅니다. 그래서 기록된 %가 3 → 2 → 3으로 흔들렸고, 이 흔들림 때문에 보정값이 44배 틀어져서 멀쩡한데 “99% 도달” 알림이 떴어요. 지금은 구간 최고값이 새로 오를 때만 보정 표본으로 쓰도록 고쳤고, 같은 일이 다시 안 생기게 회귀 테스트도 넣었습니다.
한계
- 한도 %는 계정 전체 값인데 로그는 이 PC 것뿐입니다. claude.ai 웹 대화, 클라우드 세션, 다른 PC도 같은 한도를 쓰지만 보이지 않아서, 추정선(점선)은 실제보다 낮을 수 있어요. 상태줄 실측값은 정확합니다.
- 출력 토큰이 적게 잡힐 수 있습니다. Claude Code 로그에
output_tokens가 부분값으로 남는 경우가 있어서, 한 응답의 여러 줄 중 최댓값을 쓰지만 실제는 더 클 수 있어요. - 원인 판정은 규칙 기반이라, 어떤 규칙에도 안 맞으면 “해당 원인 없음”으로 나옵니다.
- Claude Code 로그 형식은 공개 API가 아니라서 버전이 바뀌면 깨질 수 있습니다.
앞으로 할 일
작업 스케줄러 등록을 명령 하나로 할 수 있게 만들 예정입니다. 기본은 배터리 사용 중에도 실행하고, --no-battery로 끌 수 있게 하려고 해요. 진행 상황은 이슈에 있습니다.
정리 — 클로드 코드 토큰 아끼는 법
모니토큰이 내놓는 권고를 추리면 결국 이 네 가지입니다.
- 오래 쉰 큰 세션은 이어 쓰지 않는다. 캐시가 만료돼서 대화 전체를 다시 씁니다.
- 긴 대화에서 도구를 많이 부를 거면 먼저
/compact. 호출마다 컨텍스트 전체를 다시 읽습니다. - 큰 파일·이미지는 필요한 부분만. 한 번 들어간 원문은 세션 내내 끌고 다닙니다.
- 병렬 세션은 꼭 필요할 때만. 동시에 돌리면 한도가 같이 녹습니다.
그래서 제 습관은 이렇게 바뀌었습니다
저는 불가피하지 않으면 세션을 오래 켜 두지 않습니다. 예전에는 귀찮아서 그냥 켜 두는 경우가 많았어요. 그런데 모니토큰에 “공백 후 재개”와 “긴 대화 × 잦은 호출”이 계속 찍히는 걸 보고 나니, 켜 둔 세션이 공짜가 아니라는 게 눈에 보이더라고요. 쉬었다 돌아오면 이어 쓰는 대신 새 세션으로 시작합니다.
“얼마나 썼나”보다 “왜 썼나”를 알면, 다음엔 덜 쓰게 됩니다. 실직자에게는 토큰도 소중하니까요.
- 깃헙: https://github.com/reddol18/moni_token (MIT)
Comments