Claude Code는 얼마나 빠를까? 초당 토큰 수, 20,000턴으로 측정했습니다

Claude Code는 출력 속도를 절대 보여 주지 않지만, 모든 세션 트랜스크립트에는 그 속도를 계산하는 데 필요한 정보가 들어 있습니다. 40줄짜리 스크립트를 우리 세션 319개, 20,408턴, 출력 토큰 1,200만 개에 돌려 봤습니다. 중앙값 기준으로 Opus 5는 초당 63토큰, Opus 5.5는 95, Sonnet 5는 77을 스트리밍했고, 짧은 답변은 언제나 긴 답변보다 느렸습니다. 방법, 스크립트, 수치, 그리고 빠른 모드가 바꾸는 것을 정리합니다.

Claude Code는 토큰에 대해 많은 것을 알려 줍니다. /usage는 세션과 한 주 중 얼마나 썼는지 보여 주고, AgentsRoom의 세션 모니터는 입력, 출력, 캐시 읽기, 캐시 쓰기를 턴마다 세며, 상태 표시줄은 사용 중인 컨텍스트 윈도우의 비율을 출력할 수 있습니다. 하지만 사람들이 계속 찾는 그 숫자는 어디에도 나오지 않습니다. 기다리는 동안 모델이 실제로 초당 몇 개의 토큰을 만들어 내는가 하는 숫자입니다.

이 숫자는 숨겨져 있는 것이 아니라, 그냥 한 번도 계산되지 않았을 뿐입니다. 모든 세션의 모든 메시지는 ~/.claude/projects/ 아래의 JSONL 트랜스크립트에 기록되고, 어시스턴트 메시지마다 타임스탬프와 토큰 사용량이 담겨 있습니다. 그래서 우리 컴퓨터에서, 최근 4주치를 직접 계산해 봤습니다. 방법, 스크립트, 그리고 결과를 소개합니다.

데이터는 어디서 오는가

Claude Code는 세션마다 파일 하나를 ~/.claude/projects/<project slug>/<session id>.jsonl에 씁니다. 이벤트 하나에 한 줄입니다. 여기서 중요한 줄은 어시스턴트 메시지이며, 필요한 필드만 남기면 각 줄은 다음과 같습니다.

{
  "type": "assistant",
  "uuid": "24d13076-…",
  "parentUuid": "d4447285-…",
  "requestId": "req_011CepWq…",
  "timestamp": "2026-09-07T18:00:08.412Z",
  "message": {
    "model": "claude-opus-5",
    "usage": {
      "input_tokens": 2,
      "cache_read_input_tokens": 0,
      "cache_creation_input_tokens": 51591,
      "output_tokens": 200,
      "output_tokens_details": { "thinking_tokens": 0 },
      "speed": "standard"
    }
  }
}

측정을 가능하게 하는 것은 네 가지입니다.

  • timestamp는 콘텐츠 블록이 추가되는 시점에 기록되므로, 턴의 마지막 블록에는 스트림이 끝난 시각이 찍힙니다.
  • parentUuid는 바로 앞 줄, 즉 모델이 응답하던 사용자 메시지나 도구 결과를 가리킵니다. 그 타임스탬프가 요청이 나간 시각입니다.
  • requestId는 API 호출 한 번의 블록들을 묶습니다. 텍스트를 쓴 다음 도구를 호출하는 턴은 같은 requestId와 같은 usage를 가진 어시스턴트 줄을 두 개 만들기 때문에, 토큰은 줄마다가 아니라 요청마다 한 번만 세야 합니다.
  • usage.output_tokens는 사고를 포함한 요청의 전체 출력이고, output_tokens_details.thinking_tokens는 그중 얼마가 사고였는지 알려 줍니다.

파일 어디에도 첫 토큰까지의 시간은 없습니다. 측정할 수 있는 것은 턴 전체, 즉 요청이 내 컴퓨터를 떠난 순간부터 마지막 토큰이 도착할 때까지입니다. 기다리는 동안 체감하는 숫자도 이것뿐이라서, 이것을 기준으로 삼았습니다.

방법

각 requestId에 대해, 그 값을 가진 첫 번째와 마지막 어시스턴트 줄을 가져오고, 첫 번째 줄에서 usage를 읽고, 첫 번째 줄의 부모를 찾은 뒤, 부모의 타임스탬프와 마지막 줄의 타임스탬프 사이의 초로 출력 토큰을 나눕니다. 그런 다음 모델별 분포를 봅니다. 평균 하나만 보지는 않습니다. 40초짜리 턴과 2초짜리 턴은 같은 대상이 아니기 때문입니다.

출력 토큰이 없는 턴, 소요 시간이 0 이하인 턴(재개한 세션에서는 부모가 자식보다 늦은 시각으로 기록될 수 있습니다), 15분이 넘는 턴은 제외했습니다. 15분이 넘는 턴은 긴 답변이 아니라 중단된 세션입니다. 그 밖에는 아무것도 걸러 내지 않았습니다.

스크립트는 의존성 없는 Python 40줄입니다. 어디서 실행해도 컴퓨터에 있는 모든 프로젝트를 읽습니다.

import json, glob, os, statistics as st
from datetime import datetime
from collections import defaultdict

def ts(s): return datetime.fromisoformat(s.replace("Z", "+00:00")).timestamp()

turns = []
for path in glob.glob(os.path.expanduser("~/.claude/projects/*/*.jsonl")):
    by_uuid, groups, order = {}, {}, []
    with open(path) as fh:
        for line in fh:
            try: o = json.loads(line)
            except ValueError: continue
            if "uuid" in o: by_uuid[o["uuid"]] = o
            msg = o.get("message") or {}
            if o.get("type") == "assistant" and msg.get("usage") and o.get("timestamp"):
                rid = o.get("requestId") or o["uuid"]
                if rid not in groups: groups[rid] = []; order.append(rid)
                groups[rid].append(o)
    for rid in order:
        first, last = groups[rid][0], groups[rid][-1]
        out = first["message"]["usage"].get("output_tokens", 0)
        parent = by_uuid.get(first.get("parentUuid"))
        if not parent or not parent.get("timestamp") or out <= 0: continue
        dur = ts(last["timestamp"]) - ts(parent["timestamp"])
        if 0 < dur <= 900:
            turns.append((first["message"].get("model"), out, dur))

by_model = defaultdict(list)
for model, out, dur in turns: by_model[model].append((out, dur))
for model, rows in sorted(by_model.items(), key=lambda kv: -len(kv[1])):
    rates = [o / d for o, d in rows]
    print(f"{model:18s} turns={len(rows):6d} median={st.median(rates):5.1f} tok/s "
          f"weighted={sum(o for o, _ in rows) / sum(d for _, d in rows):5.1f} tok/s")

weighted 열은 전체 토큰을 전체 초로 나눈 값입니다. 긴 자율 실행이 체감하는 값이 이것이고, 중앙값은 대화형 턴 하나가 체감하는 값입니다.

수치

프랑스에 있는 Mac 한 대, 트랜스크립트 319개, 2026년 8월 27일부터 9월 25일까지의 20,408턴, 45시간의 생성으로 만들어진 출력 토큰 1,200만 개. 모든 턴이 표준 속도입니다(빠른 모드는 아래 참고). 트랜스크립트에는 Claude Code가 기록하는 이름으로 다섯 개 모델이 등장합니다.

모델턴 수중앙값 tok/s25~75 백분위수가중 tok/s
Opus 516,70862.751.5~71.869.8
Opus 5.51,10294.980.9~109.0109.3
Sonnet 542677.062.6~91.587.0
Fable 5.12,07075.166.1~82.980.0
Opus 4.810260.949.1~66.564.2

무엇보다 먼저 읽을 것이 두 가지 있습니다. 첫째, Opus 5.5는 Opus 5보다 조금 빠른 것이 아닙니다. 중앙값으로 1.5배, 가중 수치로 57% 빠르며, 긴 턴의 비중도 훨씬 높습니다. 둘째, 한 모델 안의 편차가 모델 간 차이보다 큽니다. Opus 5의 25 백분위수 턴은 초당 51토큰, 75 백분위수 턴은 72토큰으로 스트리밍합니다. 이유는 턴의 크기이고, 이는 따로 한 섹션을 쓸 만합니다.

짧은 답변은 언제나 더 느리다

다시 Opus 5를, 턴의 출력 토큰 수로 나눠 보겠습니다.

턴의 출력 토큰 수턴 수중앙값 tok/s소요 시간 중앙값
1~991,85442.11.9초
100~49910,74360.63.4초
500~1,9993,51272.811.1초
2,000 이상59978.438.8초

같은 모델, 같은 달, 같은 컴퓨터인데 한 줄짜리 답변과 긴 답변 사이에서 속도가 두 배 차이 납니다. 긴 턴에서 모델이 더 빨리 스트리밍하는 것이 아닙니다. 모든 턴은 첫 토큰이 나타나기 전에 고정 비용을 치릅니다. 요청이 나가고, 프롬프트가 처리되고, 스트림이 시작됩니다. 80토큰짜리 턴에서는 이 비용이 경과 시간의 3분의 1을 차지하고, 3,000토큰짜리 턴에서는 잡음 속에 사라집니다.

소요 시간을 출력 토큰 수에 대해 최소제곱법으로 적합하면 둘을 분리할 수 있습니다. 기울기는 스트리밍 속도, 절편은 고정 비용입니다.

모델턴당 고정 비용스트리밍 속도
Opus 51.03초81.6 tok/s
Opus 5.51.10초148.9 tok/s
Sonnet 50.45초94.9 tok/s
Fable 5.10.99초84.8 tok/s
Opus 4.81.40초69.9 tok/s

그러니 도구 호출이 많은 세션이 느리게 느껴질 때, 원인이 모델의 처리량인 경우는 드뭅니다. 원인은 턴의 수입니다. 파일 열두 개를 하나씩 읽는 에이전트는 고정 비용을 열두 번 치르고, 같은 에이전트가 한 번의 묶음 호출로 읽으면 한 번만 치릅니다. 토큰 비용 줄이기와 같은 교훈입니다. 더 빠른 모델이 아니라, 더 적고 더 큰 턴입니다.

코퍼스에서 가장 긴 턴은 Opus 5에서 236초 동안 출력 토큰 21,332개였습니다. 처음부터 끝까지 초당 90토큰입니다. 고정 비용이 상쇄되고 나면, 이것이 표준 속도에서 이 모델로 관찰한 상한입니다.

사고 토큰도 출력 토큰이다

output_tokens에는 모델이 답하기 전에 하는 사고가 포함되고, output_tokens_details.thinking_tokens가 그 양을 알려 줍니다. 우리 코퍼스에서 사고는 Opus 5가 생성한 전체의 30%, Opus 5.5에서는 18%, Fable 5.1에서는 36%, Sonnet 5에서는 54%였습니다. Sonnet 5는 주로 리뷰 작업에서 높은 추론 강도로 돌렸습니다.

이는 느린 턴을 해석할 때 중요합니다. 8초 동안 생각하고 두 줄을 출력하는 턴은 모델이 느린 것이 아니라, 보지 못한 600토큰을 생성한 턴입니다. 사고가 있는 턴은 토큰당으로 보면 사고가 없는 턴보다 약간 빠릅니다. Opus 5에서 초당 67 대 57토큰인데, 턴이 더 길어서 고정 비용을 더 잘 상쇄하기 때문입니다. 세션이 굼뜨게 느껴지는데 추론이 필요 없다면, 손댈 곳은 모델이 아니라 추론 강도입니다.

캐시 읽기가 바꾸는 것은 청구서이지 속도가 아니다

Claude Code의 거의 모든 턴은 프롬프트 캐시에 적중합니다. Opus 5의 16,680턴 중 cache_read_input_tokens가 0이었던 것은 130개뿐이고, 모두 세션의 첫 턴이었습니다. 출력 100~500토큰짜리 턴에서 캐시된 턴은 중앙값 초당 60.6토큰으로 3.4초, 캐시되지 않은 턴은 58.0으로 3.7초가 걸렸습니다. 차이는 실제로 있지만 작고, 스트리밍 속도가 아니라 고정 비용에 들어 있습니다. 캐시는 들고 다니는 컨텍스트의 가격에 관한 것이며, 그래서 AgentsRoom 터미널의 토큰 카운터는 캐시 읽기와 캐시 쓰기를 별도 수치로 보여 줍니다.

한 달 내내 안정적

누적 수치는 변화를 가릴 수 있으므로, 가장 흔한 100~500토큰짜리 턴에서 Opus 5의 주간 중앙값도 확인했습니다. 주마다 초당 63.6, 64.1, 60.9, 61.7, 56.9토큰이었고, 아직 끝나지 않은 마지막 주는 68.7이었습니다. 57에서 69 사이이고, 추세는 없습니다. 어느 날 오후 세션이 느리게 느껴진다면, 모델을 탓하기 전에 그날 하루만 대상으로 스크립트를 돌려 볼 만합니다.

빠른 모드가 바꾸는 것, 그리고 측정하지 못한 것

모든 usage 블록에는 speed 필드가 있고, 우리의 20,408개는 모두 standard입니다. Anthropic은 Claude Opus용 빠른 모드를 안내하고 있으며, CLI에서 /fast로, 또는 사용자 설정의 "fastMode": true로 켭니다. 모델이 최대 2.5배 빨라지는 대신 토큰당 가격이 더 높습니다. Opus 5.5에서는 입력 토큰 100만 개당 8달러, 출력 토큰 100만 개당 40달러이고, Opus 5와 Opus 4.8에서는 10달러와 50달러입니다. Pro와 Max 요금제에서는 구독 창과 별도로 사용 크레딧으로 청구됩니다. Sonnet과 Haiku는 지원하지 않으며, 켜면 Opus로 전환됩니다. 프롬프트 옆의 번개 아이콘이 켜져 있음을 알려 줍니다.

우리는 이 모드에 돈을 내지 않았기 때문에, 공식 2.5배 옆에 놓을 실측 수치가 없습니다. 이 모드를 쓰고 있다면 같은 스크립트로 결과를 알 수 있습니다. 턴을 usage["speed"] == "fast"로 걸러서 중앙값을 비교하세요. 그리고 수치를 보내 주세요.

에이전트를 돌리는 방식에서 달라지는 것

세 가지이고, 어느 것도 더 빠른 모델을 고르는 이야기가 아닙니다.

첫째는 예상입니다. 에이전트 일곱 개의 야간 실행이 출력 토큰 200만 개를 만든다면, 병렬로 도는 에이전트들에 나뉘어 초당 70토큰으로 8시간 분량의 생성입니다. 속도를 알아야 예약한 작업이 다음 작업이 시작되기 전에 끝날 수 있는지 판단할 수 있습니다.

둘째는 턴입니다. 턴당 고정된 1초는 30토큰짜리 확인이든 3,000토큰짜리 diff든 똑같습니다. 작은 단계마다 확인을 요청하거나 파일을 하나씩 읽는 에이전트는 그 1초에 시간을 씁니다. 그래서 우리는 무인으로 도는 에이전트의 프롬프트에 “독립적인 읽기는 묶어서 하라”고 적어 둡니다.

셋째는 카운터가 무엇을 보여 줘야 하는가입니다. AgentsRoom의 세션 모니터는 토큰과 캐시를 보여 주고, 세션이 무거워지면 빨간색으로 바뀝니다. 속도는 보여 주지 않으며, 이번 측정 뒤로는 보여 줘야 하는지 확신이 서지 않습니다. 속도는 모델과 턴 크기의 속성이지 세션의 속성이 아니고, 개발자에게 필요한 숫자는 위 표에 있는 숫자입니다. 그래서 이것은 위젯이 아니라 글입니다.

자주 묻는 질문

Claude Code는 초당 몇 개의 토큰을 생성하나요?

2026년 8월 27일부터 9월 25일까지 기록한 20,408턴에서, 출력 토큰의 중앙값은 Opus 5가 초당 63개(전체 토큰을 전체 초로 나누면 69), Opus 5.5가 95(109), Sonnet 5가 77(87), Fable 5.1이 75(80), Opus 4.8이 61(64)이었습니다. 이 수치는 요청이 내 컴퓨터를 떠나는 순간부터 마지막 토큰이 스트리밍될 때까지 턴 전체를 잰 것이므로, 실제로 기다리는 시간 그대로입니다.

/usage나 /cost에 초당 토큰 수가 표시되나요?

아니요. /usage는 요금제 할당량, 5시간 창과 주간 창, 사용 중인 컨텍스트 윈도우의 비율을 보여 줍니다. /cost는 /usage의 별칭입니다. 둘 다 속도는 출력하지 않습니다. 속도가 존재하는 유일한 곳은 ~/.claude/projects/ 아래의 세션 트랜스크립트이며, 어시스턴트 메시지마다 타임스탬프와 출력 토큰 수가 기록되어 있습니다. 이 글의 스크립트가 읽는 것이 바로 그것입니다.

짧은 답변이 긴 답변보다 느리게 느껴지는 이유는 무엇인가요?

모든 턴은 첫 토큰이 도착하기 전에 고정 비용을 치르기 때문입니다. 요청 전송, 프롬프트 처리, 스트림 시작이 그것입니다. 우리 데이터에서 이 오버헤드는 Opus 5와 Opus 5.5에서 약 1초, Sonnet 5에서 0.5초였습니다. 80토큰짜리 답변에서는 1초가 턴의 3분의 1을 차지하므로 측정 속도가 초당 40토큰으로 떨어집니다. 3,000토큰짜리 답변에서는 같은 1초가 묻혀 버리고 속도는 80 이상으로 올라갑니다. 스트리밍 속도 자체는 일정합니다.

사고 토큰도 속도에 포함되나요?

네. 각 메시지의 usage 블록은 output_tokens와 그 세부 항목인 output_tokens_details.thinking_tokens를 보고하며, 사고 토큰은 output_tokens에 포함됩니다. 우리 코퍼스에서 사고 토큰은 Opus 5가 생성한 전체의 30%, Opus 5.5에서는 18%, 주로 높은 추론 강도로 돌린 Sonnet 5에서는 54%였습니다. 오래 생각하는 턴은 느린 것이 아니라, 보이지 않는 토큰을 생성하고 있는 것입니다.

프롬프트 캐시를 쓰면 Claude Code가 빨라지나요?

출력 속도는 아닙니다. 100~500토큰짜리 턴에서 Opus 5는 요청이 프롬프트 캐시에 적중하면 중앙값 초당 60.6토큰, 적중하지 않으면 58.0으로 스트리밍했고, 턴 전체는 3.4초 대 3.7초가 걸렸습니다. 캐시가 좌우하는 것은 컨텍스트에 지불하는 비용이지, 답변이 나오는 속도가 아닙니다.

Claude Code의 빠른 모드란 무엇이고, 얼마나 더 빠른가요?

Claude Opus의 한 가지 구성으로, Anthropic은 최대 2.5배 빠르다고 설명합니다. 대신 토큰당 가격이 더 높습니다. Opus 5.5에서는 입력 토큰 100만 개당 8달러, 출력 토큰 100만 개당 40달러이고, Opus 5와 Opus 4.8에서는 10달러와 50달러이며, 구독 창이 아니라 사용 크레딧으로 청구됩니다. /fast로 켜고 끄며, 켜면 프롬프트 옆에 작은 번개 아이콘이 나타납니다. 우리가 측정한 20,408턴 중 빠른 모드로 실행된 것은 하나도 없어서(모든 트랜스크립트가 speed: standard) 실측 수치는 없습니다. 이 글의 수치는 모두 표준 속도입니다.

AgentsRoom 다운로드

모든 AI 에이전트를, 모든 프로젝트에서, 하나의 창으로 실행하세요.

무료AgentsRoom 다운로드

컴패니언 앱: 이동 중에도 에이전트를 모니터링

Claude, Codex, Antigravity CLI 또는 다른 AI 공급자를 사용하세요.

확장 프로그램 설치
Chrome Web Store

버그와 요청을 공개 백로그로 바로 보내세요.

멀티 프로젝트
멀티 프로바이더
멀티 에이전트
실시간 상태
파일 diff & 커밋
모바일 앱
라이브 프리뷰
에이전트 팀
브라우저 자동화
백로그 기반 개발
프롬프트 라이브러리
스킬 라이브러리
모든 기능 보기

계속 읽기