I measured 8 weeks of Claude Code: 87% lower cost, 86% first-try typecheck A frontend lead at a ~120k-line TypeScript codebase built claude-code-metrics, an MIT-licensed CLI that parses Claude Code's local session logs (~/.claude/projects/**/*.jsonl) to compute token-cache savings and first-attempt pass rates. Across 8 weeks and 7.5B input tokens, 98.4% of input tokens were read from cache, cutting input cost 87.4% versus no caching, while typecheck passed on the first run 86.3% of the time (205 attempts) and tests 75.2% (298 attempts). The author cautions that filtered command output can inflate pass rates, noting unfiltered test runs passed only 52.4% of the time, making 75% an upper bound. Everyone has an opinion about coding agents: they're too expensive, or they're magic, or the code they write is garbage. I lead the frontend of a ~120k-line TypeScript app where agents write most of the code, so I wanted numbers instead of opinions. It turns out the data was already on my machine. Claude Code writes every session to ~/.claude/projects/ / .jsonl . Each line is an event, and two kinds of event matter here: usage block with token counts: uncached input, cache writes split by 5-minute and 1-hour TTL , cache reads and output. Edit , Write and Bash command the agent ran, with its output. That's enough to answer two questions: I wrote a small CLI, claude-code-metrics https://github.com/diego-prieri/claude-code-metrics , that reads those files and answers both. Nothing leaves your machine. npx tsx src/cli.ts everything npx tsx src/cli.ts --since 2026-10-01 a period npx tsx src/cli.ts --project my-app sessions whose cwd contains "my-app" Over 8 weeks and 7.5B input tokens: | | Value | |---|---| | Input tokens read from cache | 98.4% | | Input cost vs. no caching | 87.4% lower | | Responses | 30,439 | Prompt caching changes the price of each input token, depending on where it comes from: | Token type | Price vs. base input | |---|---| | Uncached input | 1× | | Cache write, 5-minute TTL | 1.25× | | Cache write, 1-hour TTL | 2× | | Cache read | 0.1× | So the savings are: savings = 1 − actual / uncached actual = input×1 + write5m×1.25 + write1h×2 + read×0.1 uncached = input + write5m + write1h + read × 1 The base price cancels out, so the ratio holds for any model. In code it's a few lines: js export const MULTIPLIERS = { input: 1, write5m: 1.25, write1h: 2, read: 0.1 }; export function ratios t: TokenTotals : CacheRatios { const uncached = t.input + t.write5m + t.write1h + t.read; if uncached return { readShare: 0, savings: 0 }; const actual = t.input MULTIPLIERS.input + t.write5m MULTIPLIERS.write5m + t.write1h MULTIPLIERS.write1h + t.read MULTIPLIERS.read; return { readShare: t.read / uncached, savings: 1 - actual / uncached }; } One gotcha: Claude Code logs one line per content block , all with the same message id. If you don't deduplicate by id, you count the same response several times. An agent session re-sends a long, mostly stable prefix on every turn: system prompt, tools, project instructions, the conversation so far. Only the tail changes. That's the ideal case for caching: you pay to write the prefix once, then read it at 10% of the price for the rest of the session. This is the number I care about most, because it measures how good the agent's first attempt is, not how good it gets after five retries. | Check | Attempts | Passed on first run | |---|---|---| | Typecheck | 205 | 86.3% | | Tests | 298 | 75.2% | Each session is replayed in order: MultiEdit to a matching file .ts/.tsx/.vue arms typecheck, code files arm tests. tsc , jest , vitest , npm test , … is the error TS… , N failed , not ok . Agents love to pipe long output through head , grep or tail , and a filtered output can hide the failing line. So the CLI also reports the rate on unfiltered runs only : | Check | Unfiltered runs | Pass rate | |---|---|---| | Typecheck | 10 | 100% | | Tests | 21 | 52.4% | The samples are small, but the test number is a warning: treat 75% as an upper bound . This is also why, in my workflow, the agent never commits without a gate that re-runs typecheck and tests with full output. The code is MIT-licensed: github.com/diego-prieri/claude-code-metrics https://github.com/diego-prieri/claude-code-metrics . I'd love to see other people's numbers. If you run it, share yours in the comments.