11 TOKENS TYPED · 165,386 TOKENS READ · 6 API REQUESTS · 32¢ BILLED
Eight words go into a terminal on a Tuesday afternoon: “the auth test is failing — fix it.” Seven chapters follow those 11 tokens to two changed lines. On the way: the 21,850 tokens of instructions already loaded when they arrived, the grep-and-read loop that found the code, the prefix cache that makes re-sending everything six times affordable, and the bill at the end. The scenes play themselves — watch, or just scroll. are tappable. You are the prompt.
The program that reads your keystroke is not the model. Claude Code is a harness: it owns the tools, the files, the permission rules, and the assembly of every request, while the model it calls holds no memory of you between calls. At 14:20 nothing has been sent yet. The counter that runs through this tutorial — tokens the model reads, and what each one costs — is still at zero, and the next 21,850 tokens are assembled on your machine first.
The thing in your terminal is a — a program that assembles requests, executes tool calls, and renders output. The model itself runs behind a single HTTP endpoint, POST /v1/messages. That endpoint is : it stores nothing after it answers. So every request carries the whole conversation from the first token, not because anyone chose that design, but because there is nothing on the other side to remember it.
Eight words, 33 characters, about 11 at roughly four characters each. You can count them before sending: POST /v1/messages/count_tokens returns the exact figure for a given model, free. By 14:23 the model will have read 165,386 input tokens. Your eleven are 0.007% of that — about 15,000 tokens read for every token you wrote. Everything after this step is the other 99.99%.
Three fields carry everything. tools holds a JSON schema for every tool the model may call. system holds the , the harness’s own instructions. messages holds the conversation. They render in exactly that order — tools, then system, then messages — and that fixed order turns out to be worth roughly two-thirds of the bill. Your prompt is the last item in the last field.
The model cannot open a file. It emits a block — a tool name and a JSON argument object — and stops, with stop_reason: "tool_use". The harness reads the name, checks it against your permission rules, runs the actual ripgrep or file open, and sends the output back as a block inside the next request. Reading a file, running a test, opening a pull request: all of it is that one round trip, repeated.
The tool list is not free. The tools reference lists more than forty built-in names — Read, Grep, Bash, Agent, Skill and the rest — and each one’s name, description and is plain text in the request. Measured with the /context command, the built-in definitions run 14,000 to 17,000 tokens. That block is larger than most files Claude will read today, and it sits at position zero of every request this session sends.
max_tokens is a ceiling on both halves. It caps thinking plus answer text together, not just the answer. A request that reasons for 12,000 tokens under a 16,000 cap has 4,000 left to speak with, and stops mid-sentence with stop_reason: "max_tokens" if it runs out.
Four stop reasons a harness must branch on. end_turn means done. tool_use means run something and come back. max_tokens means truncated. refusal means a safety classifier declined, with an HTTP 200 and an empty content array — code that reads content[0] without checking breaks on exactly that response.
Why the terminal appears to type. The response arrives as Server-Sent Events — message_start, a run of content_block_delta, then message_stop. The harness prints each delta as it lands. Nothing is being typed; a stream is being rendered.
Parallel calls, one reply. A single assistant turn can contain several tool_use blocks. Every matching result has to come back in one user message: splitting them across messages is valid JSON and trains the model out of asking for parallel work.
Do not estimate with tiktoken. It is OpenAI’s tokenizer and undercounts Claude by 15–20% on ordinary prose, more on code. The counting endpoint is free and model-specific; use it.
Run /context in a fresh session, before you have typed anything, and 21,850 tokens are already spent. Eight blocks put them there, and exactly one of them is something you wrote. The counter moves for the first time here: from nothing to 21,850 tokens of context, still without a single request having been sent.
Eight blocks, measured. The are 14,000 tokens and the 4,200. Then the project CLAUDE.md at 1,800, the auto memory index at 680, skill descriptions at 450, your personal CLAUDE.md at 320, environment info at 280 — working directory, platform, shell, git branch and recent commits — and MCP tool names at 120. Total 21,850, or 11% of a 200,000-token , spent before you type.
Where an instruction lands decides what it can do. The system prompt belongs to the harness; your is delivered as a user message after it. That makes it context rather than configuration — Claude reads it and generally follows it, and nothing enforces it. Files load root-down: managed policy, then your personal file, then each CLAUDE.md found walking up from the working directory, then CLAUDE.local.md. The documented target is under 200 lines per file, because a longer one costs more tokens and gets followed less.
is the second half of what survives between sessions. Claude writes markdown into a per-project directory — a build command it worked out, a flaky test, a convention you corrected it on twice. MEMORY.md is the index, and only its first 200 lines or 25 KB, whichever comes first, load at session start; topic files are read on demand with the ordinary file tools. Everything past that cut is dropped on the next load, which is why the harness returns an error telling Claude to shorten the index once it grows past the limit.
, priced. Skills put only their one-line description in context — 450 tokens for the whole set — and a body loads when that skill is invoked. tool schemas are deferred the same way by default: only names are listed, 120 tokens, and the full schema arrives through tool search when a task needs it. Without deferral this is the largest line item people find on their first /context. A GitHub or Playwright server with twenty-plus tools can add 10,000 tokens, and five connected servers about 55,000.
Position matters more than size. The blocks are ordered by how often each changes: tool definitions and system prompt, which change when you upgrade Claude Code; then project context, which changes at /clear or /compact; then the conversation, which changes every turn. Your prompt is appended at the very end, which is exactly where chapter 04 needs it. Request 1 leaves your machine carrying 21,861 input tokens.
Rules that load only when relevant. A file under .claude/rules/ with paths: frontmatter enters context the moment Claude reads a matching file, and not before. That is the cheapest way to hold instructions for a subdirectory you touch once a month.
Imports organize, they do not save. An @path/to/file reference inside CLAUDE.md expands at launch, up to four hops deep. Splitting a 600-line file into six imports produces six tidy files and the identical token count.
Monorepos pick up other teams’ files. Walking up the tree collects every CLAUDE.md on the way, including ones written for packages you never open. claudeMdExcludes takes glob patterns and skips them; a managed-policy CLAUDE.md is the one file no individual setting can exclude.
The one route into the system prompt. --append-system-prompt puts text in the layer CLAUDE.md cannot reach. It has to be passed on every invocation, which makes it a tool for scripts rather than for sitting down to work.
Auditing what actually loaded. /context lists the memory files in play; the InstructionsLoaded hook logs each one as it loads, which is the way to catch a path-scoped rule that never fired. /doctor proposes trims for a CLAUDE.md that has grown past its usefulness.
There is no index. Claude Code does not embed your repository, does not build a vector store, and keeps no symbol table between sessions. It runs glob, it runs grep, it reads what those return — and every one of those calls is a separate API request carrying everything that came before it. The counter moves hard here: from 21,861 tokens in one request to 165,386 across six.
The obvious design is retrieval: chunk the repo, embed the chunks, fetch the nearest matches to the prompt. Anthropic built that, with a local vector database, and then removed it — plain glob and grep scored better. Four reasons, none of them about model quality. An exact match is exact where an embedding is a guess. There is no index to build or invalidate. A file edited 100 ms ago reads back as its new bytes. And nothing leaves the machine to be embedded. What replaced it is , which is the ordinary meaning of the words: it searches, on demand, with the tools you already have. (The RAG tutorial builds the design being rejected here, end to end.)
Three tools do nearly all of it. Glob matches paths by pattern and returns them newest-first. Grep runs over file contents and returns the matching lines with their paths. Read returns a file’s bytes with line numbers. This session: one glob for the auth files, one grep for refreshToken, then four reads. The grep that answered the question cost 600 tokens; reading the four files it pointed at cost 6,900. Searching is the cheap half.
The loop, priced. Request 1 goes out with 21,861 tokens and comes back asking for a glob and a grep. The harness runs both, appends both results, and sends request 2 — now 22,961 tokens, because nothing is ever removed. Six requests carry 21,861, 22,961, 27,481, 30,121, 30,851 and 32,111 input tokens: 165,386 between them, for a task whose entire visible output is a two-line diff. This is the number the rest of the tutorial is about.
A is text in the next request, and its size is the model’s whole view of what happened. The npm test output here is 1,200 tokens; a 10,000-line log is tens of thousands. Which is why a that greps a log for ERROR before Claude sees it can turn 40,000 tokens into 300, and why a tool returning more than 100,000 characters is written to a file in the sandbox instead, with a preview and a path handed back.
Delegation, stated as arithmetic. A starts a fresh, isolated context window with its own system prompt and its own tool list. It does not inherit your conversation, the skills you invoked, or the files Claude already read. It reads twelve files, spends 40,000 tokens of its own window, and returns one summary — 420 tokens land in yours. The exception is a fork, which inherits the parent conversation exactly, and therefore reads the parent’s cache. (The agent-patterns tutorial covers when delegation is the right shape at all.)
When a symbol table does help. Code-intelligence plugins give Claude go-to-definition and find-references through a language server. One call replaces a grep plus reads of four candidate files, and the server reports type errors after an edit without anyone running a compiler.
Why Glob sorts newest-first. The file you changed this morning is more often the file in question than the one untouched since 2019. Sorting by modification time puts the likely answer in the first few lines of a result the model pays for by the token.
Parallel calls are a habit you can break. One assistant turn can request several tools at once, and all their results must return in a single user message. Split them across messages and the model learns, correctly, that parallel requests are not honored — after which it serializes and every search costs a round trip.
Errors are results, not crashes. A failed tool returns a tool_result with is_error: true and a message. Claude reads the message and adapts, which is why a good error string is worth writing: it is prompt text, delivered at the moment it is relevant.
Explore skips your instructions on purpose. The built-in Explore and Plan agents omit CLAUDE.md and the git snapshot that every other subagent inherits. The main conversation reads their results with full project context, so the rules are applied once rather than paid for twice.
Re-sending the whole conversation on every turn would be ruinous at full price, and it is not full price. The API matches the start of each request against what it processed a moment ago and bills the matched span at a tenth. This chapter changes none of the token counts from chapter 03 — the same 165,386 — and changes what each of them cost: 133,275 read from cache, 32,111 written to it.
The key to the is the bytes of the request, from position zero up to a . If request 6 begins with exactly the bytes request 5 began with, that span is a hit. One byte different anywhere in the prefix and everything after it is reprocessed at full price. There is no per-file cache and no per-segment cache: it is one string comparison, running from the front.
Four prices for the identical token, against Opus 5’s $5 per million input. A fresh token bills at $5.00 per million. A token written to the cache bills at 1.25× for the five-minute and 2× for the one-hour — $6.25 or $10.00 per million. A token read from the cache bills at 0.1×, or $0.50 per million. Break-even at the five-minute TTL is the second request; at the one-hour TTL it is the third, because you paid double to write it.
Claude Code orders every request stable-first, which is why chapter 02’s ordering looked arbitrary. Layer one — system prompt and tool definitions, 18,200 tokens — changes when you upgrade Claude Code. Layer two — CLAUDE.md, auto memory, unscoped rules, 3,650 tokens — changes at /clear or /compact. Layer three, the conversation, changes every turn. A change in layer three leaves the first two cached. A change in layer one invalidates all three.
A named list, because every item on it feels free. Switching model with /model, since caches are per-model and the identical conversation on Haiku is a full miss. Changing , also part of the cache key. Turning on fast mode, which adds a header. An MCP server connecting or dropping while its tools sit in the prefix. Denying a bare tool name. Upgrading Claude Code mid-session. And compaction, by design.
A cached prefix expires after a gap with no requests, and every hit resets the timer. The default is five minutes. On a Claude subscription, Claude Code asks for the one-hour TTL instead, and drops back to five minutes once you are drawing on usage credits, because the longer write costs more. That is why the first message after lunch is slow: the prefix is gone, and the whole history is reprocessed as fresh input at $5 per million.
Four breakpoints, and a floor. A request may carry at most four cache_control markers. Below a minimum prefix length nothing caches at all, silently: 512 tokens on Opus 5, 1,024 on Opus 4.8 and Sonnet 5, 2,048 on Opus 4.7, 4,096 on Opus 4.6 and Haiku 4.5. The floor is not monotonic across generations, so a 3,000-token prompt caches on the newer model and does not on the older one.
The 20-block lookback. A breakpoint searches backward at most 20 content blocks for a prior entry. A single turn that appends more than that — common in an agentic loop with many tool results — can miss the cache with no visible cause and no error.
Parallel requests all pay. An entry becomes readable only once the first response starts streaming. Fire ten identical requests at once and all ten miss; fire one, wait for its first token, then fire nine, and nine of them hit.
The cache is per machine and per directory. The working directory, platform, shell and OS version are inside the system prompt, so two sessions in different directories build different prefixes and cannot read each other. That includes two worktrees of one repository.
Watching it live. Every response reports cache_creation_input_tokens and cache_read_input_tokens. A high read-to-creation ratio means it is working; creation staying high turn after turn means something in your prefix keeps moving. ENABLE_PROMPT_CACHING_1H=1 and FORCE_PROMPT_CACHING_5M=1 override the TTL choice.
At 14:22 the model emits an Edit block: a path, an old string, a new string. Four things happen between that block and the bytes on disk, and the model performs none of them. The counter barely moves in this chapter — one edit result and one hook line, 210 tokens between them — which is the point. The expensive part of changing code was finding it.
Edit takes three arguments: file_path, old_string, new_string. The harness requires the old string to match the file exactly, indentation included, and to match exactly once. Zero matches and two matches both fail rather than guess. It also requires that Claude has read the file in this conversation, so a write can only land on bytes the model has actually seen.
Permission rules are enforced by the harness, not by the prompt — the line between context and configuration that chapter 02 drew. There are four , cycled with Shift+Tab: manual asks before edits and commands; accept-edits waves file writes through; plan explores and blocks source edits; auto runs with background safety checks. Denying a bare tool name removes that tool’s schema from the request entirely, which is why chapter 04 listed it as a cache invalidation.
Before the edit, the harness snapshots the file. That snapshot is the a double Escape restores; it is separate from git and it survives resuming the session. After the edit, a PostToolUse runs Prettier, and its output — 120 tokens — is appended to the conversation. A hook is a shell command bound to a lifecycle event, so unlike a line in CLAUDE.md it runs whatever the model decides.
The model’s output is a sequence of content blocks: text and tool calls, nothing else. The harness turns that into your terminal — rendering the markdown, printing tool calls as one-line notices, showing the edit as a diff, collapsing npm test output into a summary. Whole categories never appear at all: the system prompt, hook output, a path-scoped rule loading. The transcript on your screen is a rendering of the request, not the request.
Write is the blunt one. Edit replaces a string it can prove is there; Write replaces the whole file. Overwriting a file Claude has not read is refused for the same reason a blind edit is: there is no way to check what is being destroyed.
Some commands never prompt. The harness keeps a built-in set of read-only Bash commands that run without asking even in manual mode. That is why git status is instant and git push is not.
Hooks can rewrite the call. A PreToolUse hook returning updatedInput changes the command before it runs — filtering test output to failures, say. Exit code 2 sends stderr back to Claude as context; plain stdout on exit 0 goes to the debug log and nowhere near the model.
Rewind is cheaper than compaction. /rewind truncates the conversation back to an earlier turn, and that shorter history is a prefix the cache was built from. Every turn since read through it, so the entry is still warm. Compaction, by contrast, builds a prefix that has never been seen.
What a restore skips. Checkpoints cover file contents, not the world. Symlinked and hard-linked paths are skipped, and anything that reached a database, an API, or a deploy is beyond recall — which is the actual reason those commands ask first.
Three minutes of work spent 32,111 tokens of a 200,000-token window — 16% of it, and the counter’s high-water mark for this session. A morning spends all of it, and the session does not end there. The harness starts deleting, in a documented order, and what it deletes decides which of your instructions are still in force afterwards.
The harness manages the window in two stages. First it clears older tool outputs — the file contents and command results nobody is referring to any more — because that is where the volume is. Only if that is not enough does summarize the conversation. Your requests and the key code snippets are preserved; detailed instructions from early in the conversation may not be.
The table, because half of it is surprising. System prompt and output style are untouched, sitting outside the message history. Project-root CLAUDE.md, unscoped rules and auto memory are re-read from disk and re-injected. A rule with paths: frontmatter, and a nested CLAUDE.md, are lost until a matching file is read again. Invoked skill bodies come back capped at 5,000 tokens each and 25,000 total, oldest dropped first, truncated from the end.
Priced honestly. To write the summary the harness sends another request carrying the same system prompt, the same tools and the same history, plus one instruction appended at the end. While the cache is warm that request reads your prefix at a tenth and spends its money generating the summary. Cold — resuming yesterday’s session — there is no prefix left, and the whole history is reprocessed as fresh input. Then the summary invalidates the conversation layer by design, because the new, shorter history shares no prefix with the old one.
Opus 5, Fable 5, Sonnet 5, and Opus 4.6 onward hold a million tokens. That moves the point where compaction fires; it does not change the arithmetic, because a million-token context is re-sent on every turn like any other. Long context is one of the two behaviours /usage names once it accounts for a tenth of recent usage — the other is cache misses. The levers stay the ones from chapter 03: /clear between unrelated tasks costs nothing, and delegating the big reads keeps them out of the window entirely.
Compact with a target. /compact focus on the auth bug keeps what you name instead of what the automatic pass guesses. A Compact Instructions section in CLAUDE.md sets the same steer for every pass, without you typing it each time.
The thrashing case. If one file or tool output is large enough to refill the window right after each summary, compaction would loop forever. The harness stops after a few attempts and reports it, which is a better failure than an expensive infinite one.
Clearing is free; compacting is not. /clear throws the conversation away with no request at all. /compact buys continuity and costs a full-history request to produce. Between unrelated tasks, the cheap one is also the correct one.
Resuming an old session is the expensive turn. The history now sits behind a possibly-changed system prompt with a long-dead cache, so the first request back can be the largest you send all week. On Pro and Max plans Claude Code offers to resume from a summary instead.
Teams multiply the window, not just the work. Each teammate in an agent team runs its own context window as a separate instance. In plan mode that comes to roughly seven times the tokens of a standard session, which is a reason to keep the roster small and the tasks self-contained.
The session ends at 14:23. Six requests, 165,386 input tokens, 2,020 output tokens, twelve tool calls, two changed lines. Here is the arithmetic at Opus 5’s published rates of $5 per million tokens in and $25 per million out, and the counter closes at $0.32 — against $0.88 for the identical session with no cache.
Split by what each token cost. 32,111 tokens were written to the cache at $6.25 per million: $0.20. 133,275 were read from it at $0.50 per million: $0.07. 2,020 output tokens at $25 per million: $0.05. Total $0.32. Uncached, those same 165,386 input tokens would have billed at $5 per million — $0.83, and $0.88 with the output. Caching turned an 88-cent task into a 32-cent one.
The ninety-percent-off headline is a long-session number. Caching only pays once the write premium is amortized. Request 1 wrote 21,861 tokens at 1.25× and read nothing, so it cost more with caching than without — 13.7¢ against 10.9¢. By request 6 the reads dominate and each turn saves about 13¢. Across an afternoon on one warm prefix the ratio approaches the full tenfold discount; across a three-minute task it lands at 2.8×.
The price sheet is asymmetric: $5 in, $25 out per million on Opus 5. is billed as output, and it is on by default because it measurably helps on planning and multi-step work. The budget can run to tens of thousands of tokens on a single request. That is the knob with the steepest cost curve, which is why /effort exists — and, per chapter 04, why changing it mid-session rebuilds the cache as well. (The reasoning-models tutorial is about what those tokens are doing.)
Scaled from one task to one engineer. Anthropic’s published figures across enterprise deployments: about $13 per developer per active day, $150–250 per developer per month, and under $30 per active day for 90% of users. Our 32-cent task is roughly a fortieth of a day. Where the long tail comes from is documented too — a session left open all day re-sending its full history, a first message after a break that missed the cache, an agent team running seven times the tokens of a single session.
/usage attributes, not just totals. It breaks recent usage down by skill, subagent, plugin and individual MCP server, and flags any behaviour accounting for a tenth or more — long context and cache misses being the two it names outright.
The two fields worth a statusline. Every response reports cache_creation_input_tokens and cache_read_input_tokens. A statusline script reading current_usage puts the read-to-creation ratio on screen, which is the fastest way to notice a prefix that stopped matching.
Half price, if it can wait. The Batches API processes the same requests asynchronously at 50% of standard rates, with most batches done inside an hour. Nothing interactive fits, but a nightly sweep over a thousand files does.
Per-user numbers across a team. OpenTelemetry export streams token and cost metrics per user and session into your own stack, and works on every setup — including the cloud providers, where Anthropic’s own dashboards see nothing.
The figure in your terminal is an estimate. /usage computes its dollar amount locally from token counts at list rates. It knows nothing about your promotional pricing or contracted discounts, so it will not match the invoice.
A receipt: one line per thing you were charged for, with the total at the bottom. Every row was earned in a chapter above, and the right margin says which. Eight words went in at 14:20; two lines came out at 14:23; 165,386 tokens passed through the model in between.