What You Need to Know
Every response from the Claude API carries a usage object. It splits the tokens the request used into separate counts. Input tokens are what you send, and output tokens are what Claude generates. Each count has its own price per token. Prompt caching stores a stable opening part of the prompt, the prefix, so later requests can reuse it. Storing it is a cache write, and reusing it is a cache read. A breakpoint marks where the cached prefix ends. A cache entry lasts for a set lifetime. A lever is any change that lowers the bill, such as caching, batching or a cheaper model.
Take a bakery that runs two Claude features. A website assistant answers customer questions against the bakery's standing product and allergen list. Every request re-sends that long list and gets a short answer back. A menu writer turns a few lines of notes into long product descriptions once a week. Some customers chat with the assistant for many turns while planning a cake order. The owner wants the bill down.
The Bill Is a Handful of Token Counts, Each at Its Own Rate
A cost model is arithmetic over the usage object, multiplied by real traffic. Anthropic's method is to price each token count in the response's usage at its own rate, then sum across the task's requests. The top-level counts are input_tokens, cache_creation_input_tokens, cache_read_input_tokens and output_tokens.
import json
# {"<model-id>": {"input": <usd per Mtok>, "cache_write_5m": <usd per Mtok>,
# "cache_read": <usd per Mtok>, "output": <usd per Mtok>}}
RATES = json.load(open("rates.json"))
def request_cost(model, usage):
r = RATES[model]
return (
usage.input_tokens * r["input"]
+ usage.cache_creation_input_tokens * r["cache_write_5m"]
+ usage.cache_read_input_tokens * r["cache_read"]
+ usage.output_tokens * r["output"]
) / 1_000_000Two facts drive nearly every later decision. First, output is priced several times input on every model. A workload that generates a lot relative to what it sends is output-dominated. One that sends a lot relative to what it generates is input-dominated. Each needs a different fix. Second, input_tokens is not all of the input. It counts only the tokens after the last cache breakpoint. On a cached request, the real input volume is the sum of all three input fields. A team reading only input_tokens on a heavily cached workload will conclude its prompt shrank when it did not.
So identify which axis dominates before choosing a lever. A long standing prefix re-sent hundreds of times a day with short answers is an input problem. Shortening the answers optimises the wrong axis. The bakery's assistant has this shape. A workload that sends two hundred tokens and generates four thousand is an output problem, and caching its prompt moves almost nothing. The menu writer has this shape. Thinking tokens are billed as output and reported under output_tokens_details.thinking_tokens. A reasoning-heavy workload is therefore output-dominated even when its visible answers are short. Do the arithmetic on one representative day of real traffic, not on one request. The shape of the traffic decides the answer.
Tracking Cost per Feature
Attribution means tying each cost to the feature that spent it. Without per-feature attribution, nobody can show that an optimisation worked. Tracking has three layers.
Per request, log the counts beside the request id and a workload label. Log successes as well as failures. The bakery labels each request as the assistant or the menu writer, so the two costs stay apart.
import json, logging
log = logging.getLogger("usage")
def record(model, feature, response):
u = response.usage
log.info(json.dumps({
"request_id": response._request_id, # the only key shared with support
"feature": feature, # what makes aggregation meaningful
"model": model,
"input_tokens": u.input_tokens,
"cache_creation_input_tokens": u.cache_creation_input_tokens,
"cache_read_input_tokens": u.cache_read_input_tokens,
"output_tokens": u.output_tokens,
"cost_usd": request_cost(model, u),
}))Per feature, aggregate the logs and alert on the ratio you expect: a cache hit rate, an input-to-output ratio, a cost per completed task. A regression should then announce itself before it appears on an invoice.
Per organisation, the Usage and Cost Admin API is the authoritative aggregate. Its /v1/organizations/usage_report/messages endpoint tracks "uncached input, cached input, cache creation, and output tokens". It reports them in buckets of a minute, an hour or a day, filterable and groupable "by API key, workspace, model, service tier, context window, data residency, or speed". The /v1/organizations/cost_report endpoint returns service-level cost breakdowns in USD. Anthropic states the reason to prefer it over your own logs: "Get precise token counts and usage patterns instead of relying solely on response token counting". The other reason is cost reconciliation against Anthropic billing. It needs an Admin API key, not a standard one. The docs also say "The Admin API is unavailable for individual accounts". Data typically appears within five minutes. Polling once a minute is the supported sustained rate.
Three instruments do three different jobs. The token counting endpoint prices a request shape before you send it. The usage object reports what one request consumed. The Usage and Cost API aggregates spend across the organisation. The bakery would count tokens before launching a new assistant prompt, read usage to cost one reply, and use the Usage and Cost API for both features together.
When Caching Pays
Caching costs are asymmetric. A cache write costs more than sending the same tokens uncached. A cache read costs a fraction of the uncached price. The break-even follows from those two prices. Caching pays off after a single cache read at the shorter lifetime, or after two cache reads at the longer one.
So caching pays when a large, stable prefix is re-sent often enough, within its lifetime, to amortise the write.
- Large. Prompts below the model minimum cacheable length "are processed without caching" and return no error. A small prefix does nothing, and the minimum varies by model.
- Stable. The cached prefix must match byte for byte. Anything volatile ahead of the breakpoint drives the hit rate to zero without warning: a timestamp, a per-request identifier, an unsorted serialised object or a varying tool list.
- Often enough. A prefix used once loses money. You pay the write premium and never collect the read discount.
- Within its lifetime. The clock is "measured from the start of the request that writes or reads the cache entry, not from response end". It "is refreshed at no additional cost each time cached content is used". Generation time counts against it too. A response that streams for several minutes uses up most of the shorter window before the next request begins.
The bakery's allergen list fits if it is long enough, since it goes out with every question, many times within each lifetime. If the assistant put a timestamp at the top of the prompt, ahead of the breakpoint, every request would miss. The menu writer's notes, sent once, fail the "often enough" test.
Choosing the longer lifetime is an economic decision. It costs more to write. It pays for itself on the first miss it prevents, because a miss re-sends the whole prefix at full price and writes it again. That makes it right for loops that wait on a person between turns. The bakery's cake-order chat is one.
Verifying is part of the change. Check the read count on each response:
response = client.messages.create(**request)
if response.usage.cache_read_input_tokens == 0:
log.warning("cache miss on a prefix that should be stable: %s", response._request_id)A zero where you expected a hit points to a silent invalidator, not a pricing surprise. Anthropic ranks caching first by measurement. As of September 2026, caching cut agent-loop cost by a factor of 2.7 to 5.3 on Anthropic's benchmarks, and cut a small triage agent bill by 83 per cent. Anthropic calls it "the largest lever by a wide margin", and notes that "cache reads are routinely the largest single component of task cost".
Current-state note (August 2026)
The dated figures behind the break-even are on the domain quick reference, because a release can move any of them. They are the write and read multipliers relative to base input price, the two cache lifetimes, the per-model minimum cacheable length and the maximum number of explicit breakpoints. The shape does not move. A write costs more than not caching, and a read costs a fraction. The longer lifetime costs more to write than the shorter one. Key on the shape, and look up the numbers.
Checkpointing a Growing Conversation
Checkpointing is deciding where the breakpoint sits when the prefix grows every turn. The API renders a request in a fixed order: tools, then system, then messages. A change at one level invalidates that level and everything after it. In a growing conversation, the settled transcript is the stable part and the new turn is the volatile part. The breakpoint belongs at the boundary between them. It must advance as that boundary moves. In the bakery's cake-order chat, each customer reply moves the boundary one turn on. Automatic caching does the advancing for you. Each turn, the previous turn becomes part of the read prefix, and only the newest content is written.
With explicit breakpoints you place them yourself, and two limits shape the design. A request carries at most a small fixed number of breakpoints. From each one, the system walks backward a bounded number of blocks looking for earlier cache entries. A conversation that grows further past the last write than that lookback window will miss. The fix is a second breakpoint, placed closer and from the start, so writes build up there before they are needed.
The remaining choices are economic. A checkpoint placed before volatile content is wasted, because the volatile content invalidates everything after it on every request. Anything inserted into the middle of a cached prefix invalidates everything downstream of the insertion. So appending is cheap and editing history is expensive. For the same reason, a context-editing pass is best done in a few large batches, not many small ones.
Configuration counts as prefix too. The thinking configuration and the resolved effort level are rendered into the prompt itself, so changing either starts a new prefix. Switching between fast and standard speed does the same. The exception, as of September 2026, is a per-message effort change, in beta on the models that support it. A system message with empty content and a new output_config.effort level takes effect from the next user turn. It leaves everything before it unchanged, so the cached prefix still matches. That is how the routine later turns of a long conversation get cheaper without paying to write the cache again.
Put frozen material first, and everything that varies after the last breakpoint. Make configuration changes at natural re-caching boundaries, not mid-conversation. Then confirm with cache_read_input_tokens that the prefix survived. For the bakery, that means the allergen list first, the settled chat next and the customer's new message last.
The Levers, in Order
Anthropic splits the levers into two groups. Free wins "cut spend without touching quality". Anthropic lists five:
- prompt caching
- token hygiene
- a prompt audit against the model you are running
- batch processing at 50% off for work that can wait up to 24 hours
- workspace spend limits as the backstop
Trade-offs "exchange cost for intelligence: model choice, effort, output caps and task budgets, an elapsed-time clock, and multi-model architectures".
Take the free wins first, in that order. Caching is the largest single measured lever. Token hygiene is the plain one: send less. Batch processing buys its discount with asynchronous delivery. Route through it anything nobody is waiting on, and nothing that anybody is. The bakery's weekly menu writer can go through batch. The assistant cannot, because a customer is waiting for each answer. Only then turn to the trade-offs. Effort is the direct dial. A cheaper tier is legitimate for any task that passes an eval with a stated pass bar, which is 5.3's material.
max_tokens and Task Budgets
One setting looks like a lever and is not one. As of September 2026 the cost guidance says: "A task budget saves money, because the model sees it. max_tokens is a safety cap: lowering it cut cost per attempt without lowering cost per solved task". The reason is that the cap "caps a single response, invisibly to the model, so lowering it does not make the model economize. The turns that needed the room are discarded and still billed". In Anthropic's internal measurement, a tight cap cut off a large share of attempts. Very few of those still passed. Attempts got cheaper and fewer tasks got solved, so cost per solved task barely moved. If the bakery halved max_tokens on the menu writer, long descriptions would stop mid-sentence and still be billed.
The correct handling is the opposite of the instinct. Set max_tokens high enough that nothing is cut off. The page suggests 64,000 for agentic work, or the 128,000 maximum when one cut-off attempt is costly. It also says to "treat stop_reason: max_tokens as a failure". Take the saving from levers the model can respond to.
A task budget is one of those levers. As of September 2026 it is a beta, set as task_budget inside output_config. It shows the model a running token countdown for the whole agentic loop. The model then trims low-value work and wraps up, instead of being cut off mid-action. The budget is advisory, and max_tokens stays the hard per-request ceiling. A mid-task change to it invalidates the cached prefix, so set it once on the first request. Size it from your own measured per-task usage.
In the exam
The guide's scope is "Token budgeting and cost management techniques for Claude applications, including token usage tracking, cost modeling, and caching techniques (prompt caching, cache check-pointing) for cost optimization". The order in that sentence is the order of the work: model the bill before you optimise it. On almost every item in this sub-skill, the first move is spotting which axis dominates.
Domain 2 owns how caching is configured: cache_control breakpoints, the identical-prefix rule and the invalidation mechanics. Domain 5 owns whether caching pays. The lifetime choice and the verification check sit here, not in 2.3. The guide's own phrase "cache check-pointing" names the breakpoint decision on a growing conversation.
Under tracking, the guide asks about per-feature attribution. An option that offers one of the three instruments for the work of another is wrong. A candidate should be able to say the caching rule in words: a large, stable prefix, re-sent often enough within its lifetime.
Caveats and Sourcing
The quick reference carries the full list of levers. The Task budgets page suggests starting a task budget at the 99th percentile of your per-task token spend, then testing up or down.
Exam Traps
Lowering max_tokens presented as a cost optimisation.
This is the most reliable distractor in the sub-skill, and it is wrong on the mechanism. The cap is invisible to the model, so responses are truncated rather than tightened, and the wasted tokens are still billed. A task budget saves money because the model can see it; max_tokens is a safety cap, and lowering it cuts cost per attempt without lowering cost per solved task. Treat stop_reason max_tokens as a failure.
Recommending caching without the conditions that make it pay, or describing it as pure saving with no write cost.
A write costs more than sending the tokens uncached and a read costs a fraction, which is why a single-use prefix loses money and a heavily reused one wins enormously. The correct answer names the conditions: a large, stable prefix re-sent often enough within its lifetime. A prefix below the model minimum is silently not cached, with no error.
Optimising the axis that is not the problem.
When the stem gives a long standing document plus short answers, the bill is input-side and answer-length changes are the distractor. When it gives short prompts and long generated reports, caching the prompt is the distractor. The arithmetic over the four usage counts decides it, and input_tokens alone understates a cached request because it counts only the tokens after the last breakpoint.
Confusing estimation, per-request measurement and organisation-level attribution, or claiming that counting tokens costs money.
The token counting endpoint prices a request before you send it and is free with its own rate limits. The usage object reports what one request consumed. The Usage and Cost API aggregates spend across the organisation and groups it by key, workspace, model and tier. An option offering one of the three for the job of another is wrong, as is measuring a change against a monthly invoice.
Practice Scenario
A lime works runs a Claude service that answers duty engineers' questions against a standing 30,000-token process manual, roughly 400 times a day, with answers of a couple of hundred tokens each. Each engineer waits for the reply before carrying on with the job. Queries arrive in clusters through the shift rather than evenly. The team's cost-reduction plan is to halve max_tokens and move to the cheapest tier. What should they do instead?
Build Exercise
Put a Price on One Workload, Then Change One Thing at a Time
What you'll learn
- How to price the token counts in usage and find the dominant axis
- How per-feature attribution turns a claimed saving into a measured one
- How to verify a cache hit and diagnose a silent invalidation
- How the cache lifetime interacts with a bursty arrival pattern
- Why lowering max_tokens truncates answers instead of shortening them
- Pick one Claude workload you already run and instrument it: log input_tokens, output_tokens, cache_creation_input_tokens and cache_read_input_tokens beside the request id and a feature name, on every call, success or failure
Why: Nothing later in this exercise is measurable without a per-request record carrying a feature label.
You should see: One structured log line per call, with all the counts present even when most are zero.
- Run a representative day and produce the actual cost split by pricing each count at its own rate. Write down which axis dominates, input or output, before you touch anything
Why: Naming the dominant axis first is what stops you optimising the wrong one, which is the single most common defect this sub-skill tests.
You should see: A per-count cost breakdown and a one-sentence conclusion naming the axis.
- Add a cache breakpoint after your stable prefix and before anything that varies, then re-run the same traffic and record the hit rate, the write and read counts, and the new cost split
Why: Watching creation tokens turn into read tokens is what makes the write premium and read discount concrete rather than abstract.
You should see: Cache creation on the first call and cache reads on the rest, with a lower total.
- Test the lifetime deliberately: send two requests a few seconds apart, then two separated by longer than the shorter lifetime, and compare the usage fields. Work out from your own arrival pattern whether the longer lifetime would pay for its higher write cost
Why: A bursty arrival pattern is exactly where the lifetime choice stops being a configuration detail and becomes an economic one.
You should see: Reads on the close pair and a fresh write on the separated pair.
- Change exactly one other thing and re-measure: run the same inputs against one tier down with a twenty-case eval and an explicit pass bar, in a separate run from the caching change so the two remain separable
Why: Two changes measured together cannot be attributed, which is what makes an invoice the wrong instrument.
You should see: A pass rate and a cost per completed task for the cheaper tier, comparable to your baseline.
- Halve max_tokens on a sample so you can watch the failure yourself: record how many responses come back with stop_reason max_tokens, whether any of them are usable, and what the truncated attempts cost
Why: The instinct that a lower cap makes the model concise survives every explanation and dies on the first measurement.
You should see: Truncated answers, unchanged or worse cost per usable answer, and stop_reason max_tokens on a share of the sample.
- Reconcile your own logs against the Usage and Cost API for the same period, grouped by model and API key, and note any gap. Then write down which change paid, by how much, and which axis it acted on
Why: The reconciliation is what turns your logs into something finance and your future self can both trust.
You should see: Two totals that agree within a small margin, and a one-paragraph verdict per change.
Sources
- Prompt caching — Claude Docs, the cache lifetime, minimum cacheable length, breakpoints, lookback and the invalidation hierarchy
- Pricing — Claude Docs, the cache write and read multipliers, the break-even rule and the batch discount
- Optimizing for cost and intelligence — Claude Docs, the per-count cost method, the lever ranking and the max_tokens finding
- Usage and Cost API — Claude Docs, the usage and cost endpoints, the grouping dimensions and the Admin key requirement
- Token counting — Claude Docs, estimating a request shape before you send it
- Task budgets — Claude Docs, the advisory loop budget the model can see, its interaction with max_tokens and choosing a starting budget
- Batch processing — Claude Docs, the discount and the asynchronous delivery window it trades for
- Messages — Claude Docs, the usage field names including the cache and thinking-token details
- Effort — Claude Docs, the per-message effort change that keeps the prompt cache
- Claude Certified Developer Foundations Exam Guide — Domain 5, Cost and Token Management — Anthropic