# What common Claude Code tasks cost, measured on each model

Written on October 27, 2026, before any run was collected.

## Question

How many tokens and dollars does each of five everyday Claude Code tasks
use on Claude Opus 5.5, Claude Sonnet 5.5 and Claude Haiku 5.5, and how often
does each model's result pass an automatic check?

## Test bed

- Repository: [pallets/itsdangerous](https://github.com/pallets/itsdangerous)
  at commit `672971d66a2ef9f85151e53283113f33d642dabd` (June 14, 2025): a
  small, well-known Python library, 1,176 lines of source, 297 tests.
- Every run starts from a fresh copy at that commit with its own virtualenv.
- Claude Code, headless (`claude -p`), with permissions skipped inside the
  copy, no session persistence, project settings only (no personal
  CLAUDE.md, hooks, plugins or MCP servers), signed in with a Claude Max
  subscription, and no router in between: the
  model asked for is the model that answers. Claude Code may still use
  Claude Haiku for its own small background calls; those are reported apart.
- Three runs of every task on every model: 45 runs.

## Tasks and their checks

1. **Commit message.** A one-method change to `exc.py` is staged. Prompt:
   "Write a commit message for the staged changes and commit them." Passes
   when exactly one commit was added, nothing is left staged, and the subject
   is 1 to 72 characters.
2. **Rename across files.** "Rename the function `want_bytes` to `to_bytes`
   everywhere in this repository, including the tests, and make sure the
   tests pass." Passes when no `want_bytes` is left in `src` or `tests`,
   `def to_bytes` exists, and all tests pass. (27 uses across 6 files.)
3. **Tests for one module.** The module's test file is deleted. "Write pytest
   tests for src/itsdangerous/encoding.py in
   tests/test_itsdangerous/test_encoding.py, and make sure they pass."
   Passes when the file exists, its tests pass, and they cover at least 90%
   of `encoding.py`.
4. **Fix a failing test.** A bug is planted: the signature age in `timed.py`
   is computed backwards, failing 5 tests. "Some tests in this repository are
   failing. Find the bug and fix it without changing the tests." Passes when
   all tests pass and no test file changed.
5. **Multi-file refactor.** "Move base64_encode, base64_decode and
   _base64_alphabet out of src/itsdangerous/encoding.py into a new module
   src/itsdangerous/_base64.py. Update every import in src and tests to use
   the new module, and keep `from itsdangerous.encoding import
base64_encode, base64_decode` working for existing users. Make sure the
   tests pass." Passes when the functions live only in the new module, no
   import in `src` or `tests` uses the old path, the old import still works,
   and all tests pass. (Doing this naively creates a circular import.)

Every prompt that touches code ends with "Run the tests with
`.venv/bin/pytest -q`." Each check was confirmed to fail on an untouched copy
and pass on a correct solution before any run.

## What is recorded

Per run, from Claude Code's own result: input, output, cache-read and
cache-write tokens, cost in dollars at Anthropic's list prices
(`total_cost_usd`; on a subscription no money changes hands, so this is the
API-equivalent price), turns, wall time, the per-model breakdown, and the check's
verdict with its details. Each observation is one dated line of
`results.jsonl`. The study stops starting runs at $30 of measured cost.

## What it can't say

Five tasks in one small Python repository. Larger codebases, other
languages, a personal CLAUDE.md or longer sessions will cost more or less.
Three runs per cell show spread, not a statistically tight average.

## Rescoring note

The first refactor check flagged a comment in encoding.py that explained the compatibility re-export. The check now ignores comment lines. Rescoring all nine saved refactor workspaces changed one result (Haiku run 2) from fail to pass.

## Change before the first counted run

Smoke tests showed that an empty home directory also hides the Claude sign-in.
The counted runs use the real home directory with `--setting-sources project`
and `--strict-mcp-config` instead, which still keeps personal CLAUDE.md files,
hooks, plugins and MCP servers out of every run.
