This is a long working note on how Claude Code works underneath, written for myself and for anyone who uses it daily and wants to understand the bill. It answers the questions I kept asking: what is actually sent to the model, how a session is stored, whether saved history makes the next session cheaper, whether MCP servers save tokens, and what to do about all of it.

Everything here comes from the official docs at code.claude.com and platform.claude.com as of October 2026, plus measurements from my own session transcript. Where I measured something myself, I say so. Where the docs were unclear, I say that too. Claude Code changes often, so check the docs before relying on a specific number.

At a glance

Question Short answer
What does the model see on each request? Everything, every time: system prompt, CLAUDE.md, tool definitions, the whole conversation, and your new message. The model keeps nothing between requests.
How many API requests is one turn? One per model reply. A turn with ten tool calls is about eleven requests, each carrying the whole conversation.
Where is my session saved? A plain-text JSONL file under ~/.claude/projects/<project>/. It keeps every message, tool call, result, and token count.
Does saved history make the next session cheaper? No. Resuming re-sends the whole conversation. What makes it cheaper is the prompt cache, and only while the cache is still warm.
What actually saves tokens inside a session? The prompt cache. In my session, 96.7% of all prompt tokens were cache reads, billed at a fraction of the normal price.
Do MCP servers save tokens? Not by themselves. A good tool saves tokens when its answer replaces reading files. Its tool definitions and outputs cost tokens, which Claude Code now limits by default.
What costs the most? Reading large files and command outputs into context, long sessions without /clear, extended thinking, and subagents that run their own conversations.

First, what a token is

Everything in this post is counted in tokens, so it helps to know what one looks like.

A token is the unit the model reads and the unit you pay for. It is not a word and not a character; it is a chunk of text somewhere in between, chosen by the model’s tokenizer from a fixed vocabulary. Common words get a token of their own; rare words, names, and numbers are broken into several. The model never sees letters, only a sequence of token IDs, which is also why it can be bad at counting the letters in a word.

Text Roughly tokenized as Tokens
The cat sat on the mat. The · cat · sat · on · the · mat · . 7
Retrieval-Augmented Generation Ret · rieval · - · Aug · mented · Generation 6
2026-10-26 202 · 6 · - · 10 · - · 26 6
Tôi muốn trả hàng sau 20 ngày T · ôi · muốn · trả · h · àng · sau · 20 · ng · ày about 10
{“id”: “returns-policy#0”, “region”: “all”} every brace, quote, colon, and comma is its own token about 18

The splits above are illustrative; exact boundaries depend on the tokenizer. The rules of thumb hold:

  • English averages about 4 characters, or 0.75 words, per token. A 1,000-word page is about 1,300 tokens. A 1M context window is roughly 750,000 English words.
  • Vietnamese, code, and JSON cost more per word. Diacritics often split a syllable into two or three tokens, so Vietnamese can take 1.5 to 2 times the tokens of the same meaning in English. Code and JSON are dense with punctuation, and each bracket and quote is a token. This is why a large JSON tool result is expensive out of proportion to what it says.
  • Whitespace counts. Indentation, blank lines, and long separators all become tokens. Pretty-printed JSON costs more than the same data on one line.

The four kinds on the bill

Kind What it is Price
Input Everything sent to the model: your prompt, the files it read, tool results, CLAUDE.md Base price
Cache write Input stored in the prompt cache for reuse 1.25x base (5-minute lifetime)
Cache read Input served from the cache instead of being processed again 0.1x base or less
Output The reply, and the model’s thinking before the reply Several times the input price

Thinking deserves a mention here because it is easy to forget: before answering, the model writes a private scratchpad, and those tokens are billed as output. In the session that wrote this post, thinking was 485,665 of 1,694,742 output tokens, about 29%. Part 8 covers how to control it.

What happens inside the model

Input and output are not handled the same way, and that difference explains most of the price gap.

How a model turns input tokens into output tokens Input tokens from the prompt and context are read in one parallel pass, which builds a cache of internal state for every token. Then the model generates output one token at a time. Each new token, including thinking tokens, is appended to the sequence and the model runs again. The thinking tokens are part of the output and also feed the model's own reply. Input tokens your question, context, files, CLAUDE.md, history already a sequence of token IDs 1. Read the input all tokens processed together, in one parallel pass builds internal state (the KV cache) for each token 2. Generate, one token at a time predict the next token from everything so far each step is a full forward pass this is what costs compute append the new token, repeat Output thinking + reply billed high Thinking tokens are output tokens too generated the same way, billed as output Why the cache helps step 1 is the expensive part of re-sending a long history. The cache keeps step 1's result for reuse, so only new tokens need the full pass. Simplified. Input is read in one pass; output is produced token by token, so each output token costs a full model step.
Input is read once, in parallel. Output is written one token at a time, and thinking is part of that output.
  1. Your input is read first. The question, the context, the files, CLAUDE.md, and the history become a sequence of token IDs. The model reads all of them in one parallel pass and builds an internal state for each token, often called the KV cache. This is the expensive part of re-sending a long history, and it is the part the prompt cache saves.
  2. The output is written one token at a time. For each new token, the model runs a full step over everything so far, picks the next token, appends it, and repeats. Each output token therefore costs a full model step, which is why output is both slower and more expensive than input.
  3. Thinking is part of the output. Thinking tokens are generated the same way and billed as output. The model reads them back before writing its reply, so they cost compute and also shape the answer.

The price follows the compute. Input is processed in parallel, so many tokens share one pass. Output is sequential, so each token pays for its own pass.

Images, PDFs, and other files

Non-text inputs are converted to tokens by their own rules.

Images are cut into 28×28-pixel patches, one visual token each, so an image costs ⌈width/28⌉ × ⌈height/28⌉ tokens. Large images are downscaled first, which caps the cost:

Image Standard tier (most models) High-resolution tier (Claude 4.7 and later)
1000×1000 1,296 tokens 1,296
1920×1080, a laptop screenshot downscaled, 1,560 not resized, 2,691
3840×2160, a 4K screenshot downscaled, 1,560 downscaled, 4,784

A screenshot therefore costs about as much as a 1,000-word page, and up to three times that on the newer models. Crop to the region that matters, and downsample unless you need fine detail.

PDFs are processed as both an image of each page and the text extracted from it. The platform docs give a 3-page PDF as about 7,000 tokens in full visual mode, so budget 2,000 to 2,500 tokens per page and more for dense pages. In Claude Code, the Read tool accepts a page range; read the pages you need, not the document.

Office files (Word, Excel, PowerPoint) are not text. Claude Code reads them through a conversion step, and converting to Markdown or CSV first is both cheaper and more accurate than a page image. Notebooks come through with their outputs, so a notebook full of plots and large dataframes costs far more than its code. Audio and video are not direct inputs; transcribe them to text first.

Two session-level consequences. Everything in the history is resent on every request, so a screenshot pasted early rides along in all later requests; twenty screenshots in a debugging session is 30,000 or more tokens on every request after them, and a /clear after an image-heavy stretch pays off. And when the information is textual, give Claude the text: a log file or an error message costs a few hundred tokens and is searchable, while a screenshot of the same thing costs 1,500 and is not.

Part 1: What happens in one turn

The model behind Claude Code is stateless. It does not remember your last message, your project, or the file it read a minute ago. Every API request must contain everything the model needs. Claude Code is the program that assembles that request, runs the tools the model asks for, and keeps the conversation going. The docs call it the agentic harness: the layer around the model that provides the tools and manages the context the model sees.

One Claude Code turn: the agent loop You type a prompt. Claude Code builds a request from the system prompt, CLAUDE.md, tool definitions, and the whole conversation so far, and sends it to the Claude API. The model replies with text or a tool call. If it is a tool call, Claude Code runs the tool locally, appends the result to the conversation, and sends the whole conversation again. When the model replies with text only, the turn ends and you see the reply. You type a prompt a new user message Claude Code builds the request system prompt + CLAUDE.md + tool definitions + the whole conversation so far + the new message Claude API one call, tokens billed Model replies text for you, or "run this tool with these arguments" Tool call? yes / no no Reply shown to you the turn ends yes Claude Code runs the tool Read, Edit, Bash, an MCP tool... Result added to the conversation back to "builds the request": the whole conversation is sent again What this means for tokens One turn can be many API calls, one per tool call. Each call sends everything that came before. The repeated part is served from the prompt cache at a fraction of the price, which is why this is affordable.
A turn is a loop, not a single request. The model never runs tools itself: Claude Code runs them on your machine and feeds the results back.

A turn works like this:

  1. You type a prompt.
  2. Claude Code builds a request: the system prompt, your CLAUDE.md files and auto memory, the tool definitions, every earlier message and tool result, and your new message.
  3. The model replies. The reply is either text for you, or an instruction to run a tool with certain arguments.
  4. If it is a tool call, Claude Code runs the tool on your machine (reading a file, running a shell command, calling an MCP server), appends the result to the conversation, and sends the whole conversation again.
  5. This repeats until the model replies with text only. Then the turn ends.

Two consequences follow. First, one turn can be many requests. The docs put it plainly: each time Claude uses tools, it sends another request carrying that batch of tool results. Second, every one of those requests carries everything that came before, so the cost of a request grows with the length of the conversation. This is why the prompt cache (Part 4) matters so much. Without it, a long session would be unaffordable.

Part 2: The context window

The context window is the maximum amount of text the model can take in one request. Everything in the request counts against it: the conversation, file contents, command outputs, CLAUDE.md, auto memory, loaded skills, system instructions, and the model’s own output.

Sizes

Current models default to a 1 million token window, including Fable 5.1, Fable 5, Sonnet 5 and later, Haiku 5.5, and Opus 4.7 and later. Opus 4.6 and Sonnet 4.6 default to 200K, with a 1M variant available by adding [1m] to the model name. A million tokens is roughly 750,000 English words, which sounds like a lot until you watch a test suite’s output land in context.

What happens when it fills up

Claude Code compacts automatically as you approach the limit: it summarises the conversation so far and continues with the summary plus the most recent messages. You can move that point earlier with /autocompact <size> (for example /autocompact 500k), the --autocompact flag, the CLAUDE_CODE_AUTO_COMPACT_WINDOW variable, or autoCompactWindow in settings.

You can also compact by hand, and this is more useful than it sounds:

  • /compact summarises the conversation and frees context. Pass focus instructions to control what the summary keeps: /compact focus on the auth bug fix.
  • /clear starts a new conversation with empty context. The docs recommend /compact when you want to continue the same work, and /clear between unrelated tasks.
  • /context shows a coloured grid of what is using the window, with suggestions about context-heavy tools and memory bloat. It also shows which CLAUDE.md and memory files loaded, and which MCP tools are deferred.

One detail that surprised me: output tokens count too. Raising CLAUDE_CODE_MAX_OUTPUT_TOKENS reduces the context available before auto-compaction triggers, because Claude Code reserves room for the reply.

Part 3: Sessions and history

Where a session lives

While you work, Claude Code appends every event to a transcript file:

~/.claude/projects/<project>/<session-id>.jsonl

<project> is your working directory path with non-alphanumeric characters replaced by -. The file is JSON Lines: one JSON record per line. I opened the transcript of the session that wrote this post. It had 8,385 lines and about 26 MB, and the records included user messages, assistant replies, tool results, file snapshots, and, on every assistant reply, a usage block with the exact token counts for that request. That usage block is where the numbers in Part 4 come from.

Two warnings from the docs. The record format is internal and changes between versions, so scripts that parse it directly can break; use /export if you want a stable copy. And transcripts are deleted after cleanupPeriodDays, which is 30 days by default.

Where a session lives and what resuming it costs While you work, every message, tool call, tool result and token count is appended to a transcript file on disk. Closing Claude Code keeps the file. Resuming loads the transcript back into context: the first API call after a resume pays to write the old conversation into the cache again if the cache has expired, and later calls read it cheaply. Compacting replaces older messages in context with a summary while the file keeps the full record. Live session (in context) system prompt, CLAUDE.md, tools, and the conversation so far sent on every API call appended as you go Transcript file on disk ~/.claude/projects/<project>/<session-id>.jsonl one JSON record per line: messages, tool calls, results, token usage close Claude Code: the file stays claude --continue / --resume transcript loaded back into context First call after resume cache read if still warm, else written again Later calls cache reads again, cheap /compact older messages in context are replaced by a summary the file keeps the full record Two different things History on disk: permanent, costs nothing to keep. Cache at the API: temporary, expires after a short idle time, and must be rebuilt after that.
Resuming brings the conversation back; the cache comes back only if it has not expired. The history is free to store; re-reading it into the model is what costs tokens.

Resuming

Command What it does
claude --continue Reopen the most recent session in the current directory
claude --resume Pick a session from a list
claude --resume <name or path> Reopen a named session or a transcript file
/resume Switch session from inside Claude Code
--fork-session or /branch Copy the history into a new session ID, leaving the original alone

Resuming reopens the session under the same ID and appends new messages to it. It restores the history, the model, the permission mode, and interrupted tool calls (marked as cut off). If the session was compacted before, it continues from the last summary plus everything after it.

Does saved history make the next session cheaper?

No, and this is the most common misunderstanding. The history on disk is just a file. It costs nothing to keep, and it saves nothing by itself. When you resume, the docs are explicit: Claude Code sends the whole conversation again, and the request reads from the cache whatever part of its prefix is unchanged and still within the cache lifetime.

So resuming a long session costs input tokens for the entire history. If the cache is still warm (Part 4), most of those tokens are cheap cache reads. If it has expired, the first request after resume writes it all into the cache again at a premium, and later requests are cheap again. On Pro and Max plans, the resume dialog shows an estimate of how much of your usage limit the saved conversation will take, which is a hint of this cost.

What does carry over cheaply between sessions is knowledge, not conversation: CLAUDE.md and auto memory (Part 5) are small and loaded every time, so Claude does not have to rediscover how your project works. A new session starts with a fresh context window, and that is usually what you want.

Part 4: The prompt cache, the thing that actually saves tokens

How it works

Prompt caching is a feature of the Claude API. When a request’s beginning (its prefix) is identical to a recent request’s beginning, the API reuses its processing of that prefix instead of redoing it, and charges much less for it. Claude Code uses it automatically.

The docs describe the cached prefix as three layers, in this order:

Layer Contents Changes when
1 System prompt, core instructions, tool definitions The tool set changes (for example, an MCP server is added or removed)
2 Project context: CLAUDE.md, auto memory, rules without a path scope At session start, or after /clear or /compact
3 The conversation Every turn, but only by appending at the end

Because each turn appends to the end, the earlier prefix is unchanged and comes from the cache. Only the new exchange is processed at full price.

What each API call sends, and what the cache does with it Three horizontal bars show the prompt sent on an early call, a later call, and a much later call in one session. Each bar grows because the conversation grows. Most of each bar is read from the cache, a small part is written to the cache for the first time, and only a tiny part is uncached. Real figures from one session: an early call wrote about 25,000 tokens to the cache and read about 31,000; the 400th call wrote about 300 and read about 225,000, with 2 uncached tokens. The prompt sent on each API call in one session read from cache (cheap) written to cache (first time seen) uncached (full price) Early call system prompt + tools, already cached from a moment ago CLAUDE.md, memory and first messages: written to cache Later call everything from before: read from cache the previous turn's messages and tool results: written once Call 400 the bar is long because the conversation is long, but almost all of it is a cache read Real figures from the session that wrote this post (from its transcript file) Early call: 2 uncached, 25,506 written to cache, 30,989 read from cache, 113 output. Call 400: 2 uncached, 346 written, 225,081 read, 256 output. Over 1,593 calls, 96.7% of all prompt tokens were cache reads.
The prompt grows with every call, but the part that repeats is read from the cache. Bars are to scale with each other only roughly.

What it costs

The platform docs give the multipliers relative to the normal input price:

Operation Price
Normal input 1x
Cache write, 5-minute lifetime 1.25x
Cache write, 1-hour lifetime 2x
Cache read 0.1x. Lower on newer models: 0.05x on Opus 5.5 and Sonnet 5.5, 0.025x on Fable 5.1 and Mythos 5.1

Writing to the cache costs a little more than normal input once. Reading from it costs a tenth or less, every time after that.

How long it lasts

The cache lifetime is 5 minutes by default, and each use refreshes it for free. Claude Code gives the main conversation a 1-hour lifetime on a Claude subscription within plan usage, and 5 minutes on an API key, usage credits, or a cloud provider. You can set it with promptCacheTtl in settings or CLAUDE_CODE_PROMPT_CACHE_TTL (5m or 1h).

This is the answer to “will it be cheaper when I come back?” If you come back within the lifetime, yes. If you come back tomorrow, the first request rebuilds the cache.

What breaks it

The docs list actions that invalidate the cache mid-session: switching models with /model, changing the effort level on most models, toggling fast mode, connecting or removing an MCP server when its tools are loaded upfront, compaction, and upgrading Claude Code. After any of these, the next request pays to rebuild the prefix.

Editing CLAUDE.md during a session does not invalidate the cache, but the edit also does not apply until you /clear, /compact, or restart.

The cache is effectively scoped to one machine and directory, because the system prompt embeds the working directory and memory paths. Two sessions in the same directory started one after another share a prefix only when the git status snapshot taken at startup matches.

My own numbers

I summed the usage blocks across the transcript of the session that wrote this post. It spanned 1,593 model replies.

Measure Tokens Share of prompt tokens
Uncached input 4,162 0.0%
Written to cache 19,927,225 3.3%
Read from cache 588,975,357 96.7%
Output 1,361,765 not a prompt token

Two individual requests show the pattern. An early request: 2 uncached tokens, 25,506 written, 30,989 read. Request number 400: 2 uncached, 346 written, 225,081 read. The prompt had grown to a quarter of a million tokens, and almost all of it was a cheap read.

Using the standard multipliers (write 1.25x, read 0.1x), the prompt side of this session cost about 86% less than it would have without caching. On models with the 0.05x or 0.025x read price, the saving is larger. This is the single biggest reason long sessions are affordable, and it is also why anything that breaks the cache in a long session is expensive.

How to check your own cache

/usage shows a “Prompt cache (main)” line with the share of input tokens served from the cache, the misses, and whether the cache is warm or cold (this line needs Claude Code 2.1.251 or later). A custom status line can show cache_read_input_tokens and cache_creation_input_tokens live.

Part 5: CLAUDE.md and memory

CLAUDE.md files are instructions and project knowledge that Claude Code loads into the request. They are the one form of persistence that is cheap, because they are small and stable, and the cache treats them as part of the fixed prefix.

What loads, and when

File Loads
Managed policy CLAUDE.md (set by an organisation) At launch
~/.claude/CLAUDE.md (your personal file) At launch
./CLAUDE.md or ./.claude/CLAUDE.md in the working directory and every directory above it At launch, concatenated from the root down
./CLAUDE.local.md (personal, keep out of git) At launch
.claude/rules/*.md without a paths field At launch, same priority as .claude/CLAUDE.md
.claude/rules/*.md with a paths field, and CLAUDE.md in subdirectories On demand, when Claude touches a matching file
Auto memory: ~/.claude/projects/<project>/memory/MEMORY.md The first 200 lines or 25 KB, whichever comes first, at the start of every conversation
Skills Descriptions at start; the full body only when used

If no CLAUDE.md exists above the working directory, Claude Code reads AGENTS.md instead.

What it costs

The docs are direct about this: CLAUDE.md is loaded into context at session start, and those tokens are present even when you are doing unrelated work. The guidance is to keep each file under 200 lines, and to ask of every line, “would removing this cause Claude to make mistakes?” If not, cut it. Imports with @path do not reduce the cost, because imported files load with the file that imports them. Knowledge that is only relevant sometimes belongs in a skill or a path-scoped rule, which load on demand.

/memory opens these files for editing, and /init generates a starter CLAUDE.md.

Part 6: Do MCP servers save tokens?

An MCP server gives Claude extra tools: a database query, a code graph, a ticket system. Three things about it cost tokens, and one thing about it can save them.

Cost 1: tool definitions

Every tool has a name and a description that the model must see to use it. In older versions, all of them loaded into every request. Claude Code now uses tool search by default on supported models: at session start only the tool names and the server’s instructions load, and the model fetches a tool’s full definition when it needs it, through a built-in ToolSearch tool.

You can tune this with ENABLE_TOOL_SEARCH: unset defers all MCP tools; auto loads them upfront while their total stays under 10% of the context window and switches to deferral above that; auto:5 sets a different percentage; false loads everything upfront. A server can be pinned upfront with alwaysLoad: true in its config. /context labels each MCP tool as deferred or loaded on demand.

Cost 2: tool output

Whatever a tool returns enters the conversation and stays there. Claude Code warns when any MCP tool output exceeds 10,000 tokens, and caps output at 25,000 tokens by default, adjustable with MAX_MCP_OUTPUT_TOKENS. Successful text results over 50,000 characters are written to a file instead of being placed in context.

Cost 3: cache invalidation

Adding or removing a server whose tools are loaded upfront changes layer 1 of the cache, so the next request rebuilds the prefix. Do that at the start of a session, not in the middle of a long one.

The saving

A tool saves tokens when its answer replaces something more expensive, usually reading files. The code-graph-rag post on this blog is the clearest example: asking the graph “who calls this function” returns a short list, where the alternative is grepping and reading several files into context. The same logic applies to any tool: a precise answer of a few hundred tokens beats a raw dump of a few thousand.

So the honest answer is that MCP servers are neutral. A focused tool with small outputs saves tokens. A chatty server with dozens of tools and large outputs costs them. The docs’ own advice is to prefer CLI tools over MCP servers where a CLI exists, and to disable servers you are not using with /mcp. /usage can attribute recent usage to individual servers, which tells you which ones earn their keep.

Part 7: Subagents

A subagent is a separate conversation that Claude Code starts to do a job and report back. Each subagent runs in its own context window, with its own system prompt and tool access. It does not see your conversation or the files you already read. When it finishes, only its summary returns to your conversation.

This is the main way to keep noisy work out of your context: run the test suite in a subagent and get back only the failures, or have one investigate a bug and return the cause. The noise stays in the subagent’s window and is discarded.

It is not free. A subagent sends its own requests, which count toward the same usage limits as your main conversation, and the docs warn that each subagent spends tokens of its own while it runs. Two settings help: route simple subagents to a cheaper model with model: haiku in their definition, and set omitClaudeMd: true to start them without your CLAUDE.md when they do not need it. A forked subagent (fork) is the exception: it inherits your full conversation, which is useful when it needs the context and costly when it does not.

Part 8: Thinking and effort

Extended thinking is the model reasoning before it answers. Those tokens are billed as output tokens, and the default budget can be tens of thousands of tokens per request depending on the model. Thinking cannot be turned off on Opus 5.5, Sonnet 5.5, Haiku 5.5, or Fable, but it can be lowered with /effort, in /config, or with MAX_THINKING_TOKENS on models that use a fixed budget. For routine edits, a lower effort level is often enough and noticeably cheaper.

Part 9: Seeing where the tokens go

  • /usage (/cost is an alias) shows, for the session: total cost, API time, wall time, code changes, and a breakdown by model of input, output, cache read, cache write, and dollars. The dollar figure is computed locally at list price and is an estimate; the Console usage page is authoritative. Totals reset on /clear.
  • /context shows what is in the window right now, including CLAUDE.md, memory, and MCP tools.
  • A custom status line can show live token counts, including cache reads and writes, and the percentage of the window used.
  • The transcript file has the exact usage of every request, if you want to analyse a session after the fact, with the caveat that its format is internal.

Part 10: Tips

These are the practices that follow from everything above, with the reason for each.

  1. /clear between unrelated tasks. The previous task’s files and outputs are still in every request until you do. The docs say to use it frequently.
  2. /compact with focus instructions when you want to continue. /compact focus on the payment refactor keeps what matters and drops the rest. Compacting resets the cache, so do it at a natural break, not mid-investigation.
  3. Use /btw for side questions. The answer never enters the conversation history, so a quick “what does this flag mean?” does not follow you around for the rest of the session.
  4. Keep sessions on one topic. A long session is cheap per request thanks to the cache, but every request still carries the whole history. Ten focused sessions cost less than one sprawling one.
  5. Do not switch models or effort levels mid-session without a reason. Each switch invalidates the cache and the next request rebuilds the prefix at the premium price.
  6. Connect MCP servers before you start, not during. Same reason: adding one changes the tool definitions at the front of the cache.
  7. Keep CLAUDE.md under 200 lines, and cut anything that does not prevent a mistake. It is loaded into every request of every session.
  8. Move occasional knowledge into skills or path-scoped rules. They load only when relevant. Imports do not help; they load with the file that imports them.
  9. Let auto memory do its job, and prune MEMORY.md occasionally. Only its first 200 lines or 25 KB load, so stale entries push out useful ones.
  10. Scope what Claude reads. Point it at the function or the file section, not the directory. Ask for grep results before full files. The context-heavy tools /context flags are usually file reads and command outputs.
  11. Pre-filter command output. BASH_MAX_OUTPUT_LENGTH caps shell output (30,000 characters by default). The docs also show PreToolUse hooks that filter output before it reaches context.
  12. Use subagents for noisy work, and put them on Haiku when the job is simple. Test runs, log searches, and broad code surveys belong in a subagent that returns a summary.
  13. Prefer a CLI to an MCP server when both exist, and disable unused servers. Fewer tool definitions, smaller outputs, and a cache that is not disturbed.
  14. Lower the effort level for routine work. Thinking tokens are output tokens, and output is the most expensive kind.
  15. Resume within the cache lifetime when you can. Coming back to a session an hour later on a subscription, or five minutes later on an API key, keeps the history as cheap reads. Coming back the next day rebuilds it.
  16. Check /usage once in a while. If the cache share is low or one MCP server dominates, you have found the next thing to fix.

A suggested workflow

The tips above are easier to apply as a routine. This is the one I use, built around the one decision that matters most: after each task, is the next task related to this one?

A token-saving workflow for Claude Code Four phases from top to bottom: set up the project once, start a session, work on one task in a loop, and end the session. After each task, decide whether the next task is related. If it is, continue in the same session and compact with a focus at a natural break. If it is not, clear the conversation so the history drops to zero while the fixed prefix stays cached. A side panel lists tools for tiny one-off jobs: the btw command, a subagent, and print mode. 1. Set up, once per project CLAUDE.md under 200 lines. Occasional knowledge in skills or path rules. Only the MCP servers you need. Cap shell and MCP output. A status line that shows context used and cache reads. 2. Start a session Right directory. Connect MCP servers before the first prompt. Pick the model and effort level once; switching rebuilds the cache. Open with a specific prompt that names the files or functions. 3. Work on one task Narrow reads: a function or line range, grep before full files. Noisy work (tests, logs, surveys) goes to a subagent on Haiku. Side questions through /btw. Corrected twice? /clear and re-prompt. Check /context when a session feels slow. task done Next task related? yes Keep the session /compact <focus> at a break then back to step 3 no /clear history drops to zero, fixed prefix stays cached 4. End the session Back soon? Resume while the cache is warm. Back tomorrow? Start fresh; the history would be re-sent in full. Keep knowledge in CLAUDE.md and memory, not in the chat. Tiny one-off jobs, no session needed /btw: a quick question, answer never enters history subagent: isolated job, only the summary returns claude -p "...": one scripted task, standalone request
The decision after each task is the one that matters most: related work stays in the session, unrelated work starts from a cleared context.

Set up once per project. Write a short CLAUDE.md, move occasional knowledge into skills or path-scoped rules, keep only the MCP servers you need, cap shell and MCP output, and add a status line that shows context and cache usage. This is where most of the per-session fixed cost is decided.

Start a session deliberately. Open in the right directory, connect MCP servers before the first prompt, choose the model and effort level once, and begin with a prompt that names the files or functions involved. A specific first prompt avoids an exploration phase that fills the context with file reads.

Work on one task at a time. Ask for narrow reads, send noisy work to a subagent, use /btw for side questions, and if you have corrected Claude twice on the same point, /clear and write a better prompt rather than arguing in a long context.

Decide after each task. If the next task is related, keep the session and /compact with a focus at a natural break. If it is not, /clear. The history drops to zero, and the fixed prefix (system prompt, tools, CLAUDE.md) is small and, when unchanged and still within the cache lifetime, is served from the cache.

End with intent. If you will be back within the cache lifetime, resume. If not, start fresh next time and let CLAUDE.md and memory carry the knowledge. A long session resumed the next day re-sends its entire history.

Many small, unrelated tasks

This is the case where the default habit, one long conversation, costs the most. Ten unrelated tasks in one session means the tenth task’s requests carry the other nine tasks’ files and outputs, and pay for them as cache reads on every request. The fix is to keep each task’s context separate. These are the tools that do that, all built into Claude Code:

Tool Use it for Why it saves tokens
/clear (also /reset, /new) Moving to the next unrelated task in the same session The conversation is emptied. Only the fixed prefix remains, and it is small
/btw A quick question in the middle of a task The answer is shown to you but never enters the history, so later requests do not carry it
A subagent (the Agent tool, or a custom one with model: haiku) A self-contained job: run the tests, find where a setting is read, check a dependency It runs in its own context window and returns only a summary. Add omitClaudeMd: true to a custom subagent that does not need your project instructions
claude -p "..." (print mode) One scripted task from the shell, or a batch of them in a loop Each call is a standalone request with no session to carry. Good for repetitive small jobs you can describe in one line
A skill or custom slash command A small task you repeat often (format a changelog, write a migration) The instructions live in the skill and load only when it runs, instead of being re-typed into every conversation
claude --model haiku for a session of trivial tasks Renames, small fixes, questions about syntax Cheaper per token, and starting the session on it avoids a mid-session switch that would rebuild the cache

Two things to avoid. Do not use /compact as a substitute for /clear between unrelated tasks: the summary still carries the old task, and compaction itself is a request that produces a summary. And do not switch directories for every small task when they belong to the same project, because the cache prefix is scoped to the directory and each switch starts cold.

Using memory and the cache on purpose

Parts 4 and 5 explained what the prompt cache and the memory files are. This section is about using them deliberately. They solve different problems: memory carries knowledge between sessions, and the cache makes the repeated part of each request cheap. Both work best when you decide what goes where, instead of letting it happen.

Where knowledge should live

Every piece of knowledge you give Claude has a storage cost, and the storages differ. CLAUDE.md and auto memory are paid on every session. Path-scoped rules and skills are paid only when used. The code itself costs nothing until Claude reads it. So the question for each fact or instruction is not “is this useful?” but “where does it cost the least for the benefit it gives?”

Where should this piece of knowledge live? A chain of five yes-or-no questions. Can Claude get it by reading the code? If yes, store it nowhere. Is it needed on every task in this project? If yes, CLAUDE.md. Does it apply only to certain files or folders? If yes, a path-scoped rule. Is it a procedure you run sometimes? If yes, a skill or custom command. Is it something you learned while working, such as a preference or a correction? If yes, auto memory. Otherwise it is task state and belongs in the conversation or a plan file. Where should this piece of knowledge live? Can Claude get it by reading the code? yes Nowhere. Let it read. Stored copies go stale and cost tokens every session no Needed on every task in this project? yes CLAUDE.md loads at launch, every session; keep it under 200 lines no Only for certain files or folders? yes A path-scoped rule in .claude/rules/ loads only when Claude touches a matching file no A procedure you run sometimes? yes A skill or custom slash command description loads at start; the body only when used no Learned while working? a preference, a correction, a fact not in the code yes Auto memory say "remember that..."; first 200 lines load each session no: it is task state. Keep it in the conversation or a plan file, not in memory.
Each answer picks a storage with a different token cost: CLAUDE.md and memory are paid on every session, rules and skills only when used, and the code costs nothing until it is read.
Storage Loads Put here Do not put here
CLAUDE.md (project) Every session, at launch Build and test commands, conventions, the two or three mistakes Claude keeps making, the “why” behind unusual choices File trees, architecture that can be read from the code, long how-to guides
~/.claude/CLAUDE.md (personal) Every session, every project Your own preferences: response style, commit message format, tools you prefer Anything specific to one project
.claude/rules/*.md with paths When Claude touches a matching file Rules that apply to one area: how migrations are written, what the API layer must not import Rules that apply everywhere (those belong in CLAUDE.md)
Skills and custom commands Description at start, body when used Procedures you run sometimes: release steps, a review checklist, a report format Facts (a skill is a procedure, not a notebook)
Auto memory (MEMORY.md and its files) First 200 lines or 25 KB of MEMORY.md, every session Things learned while working: a preference you stated, a correction, a fact about the project that is not in the code Task progress, temporary state, anything the code already says

Writing a CLAUDE.md that earns its tokens

  • Apply the docs’ test to every line: would removing it cause Claude to make a mistake? If not, cut it. A 60-line file that Claude follows beats a 300-line file it skims.
  • Write the why, not the what. “Use pnpm, not npm; the lockfile breaks otherwise” is worth a line. A list of folders is not; Claude can list them itself.
  • Imports do not save anything. A file pulled in with @path loads together with the file that imports it, every time. Use imports to organise, not to hide size.
  • Edits apply at the next /clear, /compact, or restart, not mid-session. They do not disturb the cache, so you can edit freely and the change takes effect on the next fresh context.
  • Subagents do not receive auto memory, and a custom subagent can skip CLAUDE.md with omitClaudeMd: true. If a subagent needs a rule, put it in the subagent’s own definition.

Keeping auto memory useful

Auto memory is the notebook Claude keeps for a project, and only the first 200 lines or 25 KB of its index load each session. Two habits keep it worth its cost. Tell Claude explicitly when something should be remembered (“remember that we deploy from the release branch”), so the note is written in your words rather than inferred. And open /memory now and then to delete entries that are stale or that the code now makes obvious, because every surviving line is loaded into every session from then on.

Memory tools beyond the built-ins

For day-to-day work in a codebase, the built-in memory is the best option: it is the cheapest in tokens, it lives in plain files you control in git, and the cache treats it as part of the fixed prefix. External tools earn their place in specific situations.

Tool What it does When it is worth it What it costs
@modelcontextprotocol/server-memory, the official MCP memory server Keeps a small knowledge graph of entities, relations, and observations in a local JSON file. Claude creates and queries it through tools Structured, queryable memory shared across projects or across MCP clients (Claude Desktop, Cursor, and others) Tool definitions and results enter the context; the graph grows unless pruned; Claude has to decide to call it, unlike CLAUDE.md, which is always loaded
annotate and glosses in code-graph-rag Attaches a durable note to a function or class in the code graph, for example “safe because validate() runs first”. Each note is graded EXACT, STALE, or MOVED as the code changes Memory about the why of code, which is not in the code and gets lost when files are renamed Only available with code-graph-rag; notes live in the graph, not in git
Hosted memory services (mem0 and similar) Vector memory with search by meaning, shared across agents Products with end users that must remember things long term Data leaves your machine; one more system to run; more than coding work needs

A reasonable setup: built-in memory as the base, annotate for notes tied to code if you use the graph, and a memory server only when several clients must share it. Whatever you choose, prune it on a schedule. Every line that survives is a token paid on every session.

Keeping the cache warm

The cache is three layers (Part 4), and each layer is only reused while it stays identical. The table lists what changes each layer and what to do instead.

Action What it breaks What to do instead
Switching models with /model Layer 1, the system prompt and tools Choose the model at session start. For a run of trivial tasks, start a separate session on a cheaper model
Changing effort or toggling fast mode Layer 1 on most models Set it once per session
Adding or removing an MCP server whose tools load upfront Layer 1 Connect servers before the first prompt
Upgrading Claude Code Layer 1 Upgrade between sessions, not during one
/compact or auto-compaction Layers 2 and 3 are rebuilt Compact at a natural break, with a focus, and not more often than needed
/clear Layer 3 is emptied; layers 1 and 2 are reused if unchanged and still within the lifetime This is the cheap reset; use it between unrelated tasks
A pause longer than the cache lifetime Everything expires See the lifetime note below
Starting a new session after committing A new git status snapshot in the prefix Sessions started back to back share the prefix only if the snapshot matches; do not count on it across a commit

The lifetime. On an API key the cache lives 5 minutes from its last use, so a coffee break costs a full rebuild on the next request. On a subscription within plan usage, Claude Code gives the main conversation an hour. If you pause often and pay by the token, CLAUDE_CODE_PROMPT_CACHE_TTL=1h (or promptCacheTtl in settings) is a trade: a 1-hour write costs 2x base input instead of 1.25x, but reads stay at 0.1x or less, so it pays off as soon as a pause would have forced a rebuild.

Resuming. The same rule applies to claude --continue: within the lifetime, the old conversation comes back as cache reads; after it, as a full write. Decide whether to resume or start fresh on that basis.

One project with several systems

Should a large project made of several systems, say a store, an ERP connector, and a front end, live in one Claude Code project? Yes, as long as the knowledge is layered rather than flat. The loading rules are built for exactly this:

  • CLAUDE.md files in the working directory and its parents load at launch. A CLAUDE.md in a subdirectory loads only when Claude touches a file there. So keep the root CLAUDE.md short: shared conventions and one line per system saying where it lives. Give each system its own CLAUDE.md in its folder. Working on the store then costs nothing for the connector’s instructions.
  • Path-scoped rules do the same for narrower areas: a rule with paths: ["services/erp-connector/**"] loads only when that code is involved.
  • Do not describe the architecture in the root file. Claude can read the code; the root only needs to say what is where.

Three things to watch:

  1. Auto memory is tied to the directory you start in. Start from the root today and from services/store/ tomorrow, and you get two separate memory folders. Pick one starting point and keep it, or set autoMemoryDirectory in settings so both share one.
  2. The cache prefix is tied to the directory too. Starting from the same place lets sessions that follow each other reuse the prefix.
  3. A flat CLAUDE.md that covers every system is the expensive mistake, because all of it loads on every session for every task.

When the systems are separate repositories, claude --add-dir ../erp-connector gives one session access to another directory without merging repositories. For parallel work on two systems, claude --worktree creates a git worktree, which is its own project with its own memory and cache.

If you use code-graph-rag, index each system as its own project and group them in a workspace. One MCP server then serves the workspace, and the graph keeps the links between services, such as which connector calls which store endpoint. That is what answers “if I change this API, which system breaks?”

Check it, do not guess

  • /usage shows the share of input tokens served from the cache and whether the cache is warm or cold (Claude Code 2.1.251 or later). A session that is mostly cache reads is working as intended; a low share means something in the prefix keeps changing.
  • A status line can show cache_read_input_tokens and cache_creation_input_tokens as you work. Watching the write counter spike after an action tells you exactly which habit is expensive.
  • /context shows which CLAUDE.md and memory files are loaded and how much room they take. If memory is a large block, it is time to prune.

A daily routine that makes saving a habit

Tips are only useful if you remember them, and in the middle of a bug nobody remembers token advice. The better approach is to give the day a shape that saves tokens by itself. The mechanics in this post reward one particular shape: a few long sessions on related work, interruptions kept on the side, and small tasks done together once. Plan the day that way and the saving happens without thinking about it.

A day shaped around how Claude Code bills A timeline of one working day. A short planning step in the morning. Two deep blocks, each one session of related tasks. Above the timeline, an urgent lane: an urgent request opens a separate session or worktree and leaves the deep session untouched. Below the timeline, a small-task inbox collects minor tasks during the day instead of doing them as they arrive. At the end of the day, the inbox is processed in one batch session with clear between items on a cheaper model, followed by a short wrap-up that writes memory, checks usage, and sets tomorrow's first prompt. Urgent lane Urgent request arrives new terminal, new session (or a worktree) /btw if it is only a question handled on the side deep session untouched morning evening Plan 10 minutes group tasks pick models leave room Deep block A: one session related tasks only, specific first prompt /compact <focus> at a boundary no model switch, no long pause /clear when the block ends Deep block B: one session a different topic, fresh context noisy work in subagents small things that come up: into the inbox, not the session Batch the inbox one session, cheap model /clear between items claude -p for the mechanical ones Wrap memory /usage tomorrow's first prompt Small-task inbox Collect, do not do: a rename, a doc tweak, a question that can wait each item written down in one line; none of them enters a deep session end of day
Long sessions on related work, interruptions kept on the side, and small tasks batched once. The day's shape does the saving, so you do not have to think about tokens while you work.

Morning: ten minutes of planning

Before opening Claude Code, list what the day holds and sort each item into three kinds:

Kind Looks like Where it goes
Deep Needs context, takes an hour or more: a feature, a refactor, an investigation A focused block, one session per group of related items
Small Minutes, self-contained: a rename, a doc fix, a quick question that can wait The inbox, processed in one batch at the end of the day
Room Nothing yet, but something will come Twenty to thirty percent of the day left unassigned

Then group the deep items so that each block contains related work, and decide the model and effort level for each block now. Choosing up front prevents the mid-session model switch that rebuilds the cache. Write the plan down, in a plan file or your notes, not in a Claude session: it is task state, and task state does not belong in memory.

Focused blocks: one session, one topic, no gaps

Each block is a single session. Start with a specific prompt that names the files, keep the session as long as the work stays related, and /compact with a focus at the boundary between items. Send noisy work to a subagent. Keep the block moving: on an API key the cache expires after five minutes idle, so a long pause in the middle of a block costs a rebuild on the next request. Take breaks between blocks, not inside them. When the block ends, /clear.

Room for urgent work: isolate it

An urgent request is the moment the habit is tested. The instinct is to type it into the session that is open. Do not. It drags unrelated files into a deep session, every later request carries them, and if you /clear to deal with it you throw away the context you built. Instead:

  • If it is a question, /btw answers it without touching the history.
  • If it is a task, open a second terminal and start a new session in the same directory. It has its own conversation, and within the cache lifetime it reuses the same fixed prefix, so it is cheap to start. If it touches the same files you are editing, claude --worktree gives it a separate copy of the repository.
  • When it is done, close that session and go back to the deep one, which is exactly as you left it. If the interruption was long, its first request rebuilds the cache once; that is still far cheaper than having polluted it.

The room you left in the morning is what makes this possible. A day planned to the minute has no second terminal.

End of day: batch the inbox

During the day, small tasks go into a list, not into a session. At the end of the day, open one session for the whole list:

  • Start it on a cheaper model and a lower effort level; small tasks do not need more.
  • /clear between items. Each item then starts from the small fixed prefix, which stays warm across the batch, so the setup cost is paid once for the whole list rather than once per item.
  • For the mechanical ones, a shell loop over claude -p "..." is simpler than a conversation.
  • Any item you find yourself doing every week becomes a skill or custom command, so next time it is one line.

The batch is cheap for a structural reason: each small task gets a fresh, tiny context instead of riding inside a deep session’s quarter-million-token history, and the items share one warm cache.

Wrap-up: five minutes

  • Tell Claude what to remember, in one short session or at the end of the last one: “remember that the staging deploy needs the release branch”. Prune anything in /memory that the day made obsolete.
  • If you corrected Claude on the same thing twice today, add one line to CLAUDE.md so it does not happen tomorrow.
  • Write tomorrow’s first task as a specific prompt, so tomorrow starts with a focused block instead of an exploration.
  • Look at /usage. Note the cache share and the heaviest MCP server. If a number looks wrong, that is tomorrow’s adjustment.
  • Do not leave a long session to resume in the morning. The history would be re-sent in full. Start fresh and let memory carry the knowledge.

Weekly: a short review

Once a week, trim MEMORY.md and CLAUDE.md, disable MCP servers you did not use, and turn the small tasks that repeated into skills. Ten minutes a week keeps the fixed cost of every session from creeping up.

Check yourself

Quiz: how well do you know Claude Code's mechanics?

You scored out of .

Summary

Claude Code is a loop around a stateless model: every request carries the whole conversation, and a turn with tool calls is several requests. The context window is large but fills with file contents and outputs, and compaction trades detail for room. Sessions are saved as JSONL transcripts that cost nothing to keep and nothing to lose, but resuming one re-sends everything. The prompt cache is what makes long sessions affordable, with reads at a tenth of the price or less, as long as nothing disturbs the prefix. CLAUDE.md and memory are the cheap, persistent knowledge; MCP servers and subagents are neutral tools that save or cost tokens depending on how they are used. The practical rules are short: clear between tasks, compact with intent, keep the prefix stable, keep memory small, and keep the noise out of context.