Claude Code Cost Control for Teams
Claude Code cost control is a three-layer setup: visibility (/usage per session, OpenTelemetry per user and team), hard caps (seat allowances, usage-credit spend limits, Console workspace limits, --max-budget-usd for unattended runs), and a managed model-and-effort policy. Spend scales with context size, model, effort and the number of agents running, so caps without visibility only move the surprise.
This page is for the tech lead or platform owner who has just been asked by finance why the Claude Code line doubled, and cannot say which team, repository or pipeline drove it. Developers who want to cut their own session’s token use should start at performance optimization; the organization-level budgeting method lives in AI usage cost governance.
What a working Claude Code cost-control setup gives you
Section titled “What a working Claude Code cost-control setup gives you”- A per-session answer in
/usageand/context, and a per-user, per-team and per-repository answer in your own metrics backend through OpenTelemetry - The right cap for how your organization pays: seat allowance and usage-credit limits, Console workspace limits, or cloud-provider budgets
- A dollar ceiling on every
claude -pjob in CI, with the cost of each run in its JSON output - A managed-settings policy that pins which models and effort levels people can run, instead of a wiki page nobody reads
- A way to show that the savings did not cost quality: spend per accepted change, not spend alone
Where Claude Code spend comes from
Section titled “Where Claude Code spend comes from”Every request re-sends the conversation: the system prompt, CLAUDE.md, tool definitions, and every earlier message and tool result. Prompt caching makes that history cheaper to re-read, not free. Four things move the bill:
- Context size. A session that was never cleared re-bills yesterday’s work on every turn. After a break longer than the cache lifetime, the next message re-processes the whole context at full price.
- Model and effort. Thinking tokens bill as output tokens, and a higher effort level buys more thinking on every request.
- Agents you are not watching. Each subagent, dynamic-workflow agent and agent-team teammate sends its own requests. Scheduled tasks (
/loop), goal check-ins and cross-session messages start new turns while a session sits idle, each carrying the full context. Anthropic’s cost documentation puts agent teams at “approximately 7x more tokens than standard sessions when teammates run in plan mode”. - Automation. CI jobs have no human pressing Escape when a loop goes wrong.
For a baseline, Anthropic’s cost documentation (checked 2026-09-26) reports that across enterprise deployments the average is “around $13 per developer per active day and $150-250 per developer per month, with costs remaining below $30 per active day for 90% of users”. Compare your own numbers with that range after a pilot, not before it.
Which Claude Code spend controls apply to your setup?
Section titled “Which Claude Code spend controls apply to your setup?”How your organization pays decides where you see spend and where you cap it. Pick your row before you configure anything:
| Your setup | See spend | Cap spend | Per-user numbers |
|---|---|---|---|
| Claude for Teams or Enterprise | Spend report in org analytics (usage-credit spend only; usage inside the seat allowance is not metered in dollars) | Seat allowance, then usage-credit spend limits per organization, group or member in Admin settings > Usage | Spend report CSV; Enterprise Analytics API on Enterprise |
| Claude Console (API) | Console usage page and the auto-created “Claude Code” workspace | Workspace spend limit, plus a workspace rate limit | Console dashboard; Claude Code Analytics API |
| Amazon Bedrock, Google Cloud’s Agent Platform (formerly Vertex AI), Microsoft Foundry | Your cloud billing console | Your cloud’s budget controls, or per-user spend limits on a self-hosted Claude apps gateway | OpenTelemetry, the Claude apps gateway, or an LLM gateway such as LiteLLM |
| Individual Pro or Max | Plan usage bars in /usage | Monthly spend limit on usage credits | Not applicable |
OpenTelemetry works on every row, and it is the only option that streams per-user cost into your own stack in near real time. On the cloud-provider row, Anthropic’s analytics dashboards and the Claude Code Analytics API do not see the usage at all, so telemetry or a gateway is your only per-user view.
Set up Claude Code cost visibility, then caps
Section titled “Set up Claude Code cost visibility, then caps”-
Read one session with
/usage./usageis the command;/costand/statsare aliases of it. The Session block shows the session’s dollar figure, a per-model token breakdown and aPrompt cache (main)line with the share of input served from cache and the number of misses. On Pro, Max, Team and Enterprise plans, the same screen attributes recent usage to skills, subagents, plugins, MCP servers and heavy loops, and flags any behaviour, such as long context or cache misses, that accounts for 10% or more of it. Pressdorwto switch between the last 24 hours and the last 7 days.Two limits matter. The dollar figure is computed locally at list price, so on a subscription it is not your bill. The breakdown covers only this machine, not other devices or claude.ai.
-
See what fills the context. Run
/contextfor the split between system prompt,CLAUDE.md, tools and conversation. Configure the status line to show context use and cost on every turn, and run/insightsfor an HTML report on where recent sessions went wrong (the analysis itself counts against your usage). -
Export OpenTelemetry for the team view. Environment variables are the whole setup. Push them through managed settings (see enterprise integration) so no developer can forget them:
{"env": {"CLAUDE_CODE_ENABLE_TELEMETRY": "1","OTEL_METRICS_EXPORTER": "otlp","OTEL_LOGS_EXPORTER": "otlp","OTEL_EXPORTER_OTLP_PROTOCOL": "grpc","OTEL_EXPORTER_OTLP_ENDPOINT": "http://otel-collector.internal:4317","OTEL_RESOURCE_ATTRIBUTES": "department=payments,team.id=checkout,cost_center=eng-123","OTEL_METRICS_INCLUDE_REPOSITORY": "true"}}Set
OTEL_EXPORTER_OTLP_PROTOCOLexplicitly, because Claude Code has no default protocol. Each key inOTEL_RESOURCE_ATTRIBUTESbecomes a label on every metric, soclaude_code.cost.usagearrives sliced by department, team and model.OTEL_METRICS_INCLUDE_REPOSITORY(v2.1.269 or later) addsvcs.*repository labels, which answers “which repository drove the spend”. If the collector is reachable from outside a trusted network, addOTEL_EXPORTER_OTLP_HEADERSwith a token from your secret store, never a literal in the file. -
Graph the series that answer finance. Every name carries the
claude_code.prefix; leave it out of a query and the filter matches nothing.Metric or event What it gives you claude_code.cost.usageEstimated cost in USD, by model and by your resource attributes claude_code.token.usageInput, output and cache tokens: the driver behind the cost claude_code.pull_request.count,claude_code.commit.count,claude_code.lines_of_code.countThe output side of the ratio claude_code.api_error(event)Rate-limit and API errors, as log events: the early warning before anyone complains that Claude is slow The full catalog, including traces, is on the agent observability page.
-
Report at your contracted rates. Every figure Claude Code shows (
/usage, the status line, OpenTelemetry and the--max-budget-usdlimit) uses list price unless themodelPricingmanaged setting says otherwise. Set amultiplierbelow 1 for a flat discount (above 1 for an internal chargeback markup, v2.1.271 or later), or per-modeloverridesfrom your contract. Claude Code does not fetch these rates from the Console, so update the setting when the contract changes, and it ignores the key outside managed settings. When it is in effect, theTotal costline in/usagecarries the noteat your organization's configured rates. The figures are still estimates, not an invoice. -
Set the cap for your row. On Teams and Enterprise, the seat allowance is the default ceiling; turn on usage credits only together with a spend limit at organization, group or member level. On the Console, set a spend limit on the “Claude Code” workspace and a workspace rate limit, so Claude Code cannot starve your production API traffic. On cloud providers, use the provider’s budget alerts, or a gateway that enforces per-user limits. Whatever the row, tell developers which message means which ceiling: “You’ve hit your weekly limit” is the seat allowance, while “You’ve hit your individual spend limit” is a usage-credit limit an admin can raise in Admin settings > Usage.
To verify telemetry before the rollout, start claude with OTEL_METRICS_EXPORTER=console and OTEL_METRIC_EXPORT_INTERVAL=10000, ask it anything, and wait for a claude_code.session.count datapoint in the terminal. Then switch back to otlp and look for the same series in your backend.
How to cap spend on unattended Claude Code runs
Section titled “How to cap spend on unattended Claude Code runs”Interactive sessions self-correct because a person notices a runaway loop. Headless runs do not. Give every claude -p invocation a dollar ceiling and read its cost from the output:
# CI step: read-only triage with a hard dollar cap and a turn limit.# RUN_ID is the failed workflow run; its failure log is piped in as input.gh run view "$RUN_ID" --log-failed | \claude -p "Triage these failing tests and propose fixes. Do not edit files." \ --tools "Read,Grep,Glob" \ --max-budget-usd 5.00 \ --max-turns 12 \ --output-format json > triage.json
jq '{cost: .total_cost_usd, basis: [.modelUsage[].costBasis], budget_refusals: .subagent_stats.refused.budget}' triage.json--max-budget-usd stops the run once spend reaches the cap, and spend from subagents counts toward it. From v2.1.217, reaching the cap also blocks new subagents and stops background subagents that are still running. --max-turns exits with an error after that many agentic turns; the CLI reference documents it and v2.1.283 accepts it, although claude --help in v2.1.283 does not list it (checked 2026-09-26). Both flags work in print mode only. With --output-format json, the result carries total_cost_usd, a modelUsage entry per model whose costBasis says whether list price or your modelPricing rates were used, and subagent_stats.refused.budget, the number of subagents the cap blocked. Log all three per job.
Set a model and effort policy for Claude Code
Section titled “Set a model and effort policy for Claude Code”Model and effort are the largest levers you control, and the order in which you pull them matters. The rule this site follows: start on the tool’s default model, tune effort before switching model, and switch model only when your own evals say so.
- Default work. On the
latestrelease channel (v2.1.280 and later), Claude Code defaults to Claude Opus 5.5 atmediumeffort on Pro, Max, Team, Enterprise, the Anthropic API, Claude Platform on AWS, Bedrock and Google Cloud’s Agent Platform. Microsoft Foundry is the exception: there the default is Claude Sonnet 4.5. Anthropic’s own claim is that Opus 5.5 atmedium“matches or exceeds Opus 5 athigh”. Thestablechannel (v2.1.274 on 2026-09-26) still runs older defaults, so check/modelbefore you write a policy around them. - When cost dominates. Claude Sonnet 5 for everyday work and Claude Haiku 4.5 for mechanical, high-volume subagents. Prices live on the models hub, not here.
- Deliberately, by hand. Claude Fable 5.1 (
/model fable) for the longest-horizon reasoning. It is never a default, it has its own weekly limit in/usage, and depending on plan and seat tier it can bill to usage credits.
Enforce the policy in managed settings instead of asking people to remember it:
{ "availableModels": ["opus", "sonnet", "haiku"], "enforceAvailableModels": true, "maxEffortLevel": "high", "env": { "CLAUDE_CODE_SUBAGENT_MODEL": "sonnet" }}availableModelsrestricts which models people can pick, including in subagent frontmatter andCLAUDE_CODE_SUBAGENT_MODEL. This example leaves Fable out; add"fable"for the teams whose evals justify it. On Foundry theopusalias resolves to Opus 4.6, so pin full model IDs there.enforceAvailableModels(v2.1.175 or later) makes the Default option obey the list as well. Without it, picking Default still resolves to the account’s default model.maxEffortLevel(v2.1.267 or later) caps effort on every provider, including Bedrock, Google Cloud and Foundry. A cap belowxhighmakes ultracode unavailable, which is the point for most teams and a real loss for a few.CLAUDE_CODE_SUBAGENT_MODELsets the model for subagents and workflow agents that are not assigned one another way. A definition’s ownmodelfield still wins, so pinmodel: haikuon custom subagents that only run tests or summarize logs.deniedModelsandavailableModelsMatch: "exact"(both v2.1.283,latestchannel) hold back a specific new release that an allowlist entry would otherwise let through.
Deploy these keys together in the highest-ranked managed source you use. By default Claude Code reads only that source, so an allowlist in a managed-settings.json file is ignored when the admin console also delivers settings.
Trim context before it reaches the bill
Section titled “Trim context before it reaches the bill”The token-level tactics are on performance optimization. These have team-wide impact:
/clearbetween unrelated tasks. It costs nothing and resets the session total./compactis itself a large request, because it reads the whole conversation it summarizes; use it when you need continuity, not as a reflex.- Keep MCP tool search on. MCP tools are deferred by default, so only tool names enter context until Claude uses one.
ENABLE_TOOL_SEARCH=falseloads every definition upfront, and anauto:Nthreshold loads them upfront while they stay under N% of the context window. Prefer a CLI such asghover an MCP server where one exists: it adds no tool listing at all. - Filter verbose output with a hook. A
PreToolUsehook that rewritesnpm testto return only failures turns tens of thousands of tokens into hundreds. - Move workflow instructions from
CLAUDE.mdinto skills, which load only when invoked. - Stop idle spenders. Review the Loops rows in
/usageand cancel scheduled tasks nobody reads.
How do you prove the savings did not cost quality?
Section titled “How do you prove the savings did not cost quality?”A cheaper model that produces code your tests reject is not a saving: it moves the cost into review and rework. Measure the ratio, not the numerator:
- Track cost per accepted change. Divide
claude_code.cost.usageby merged, non-reverted pull requests for the same team and period. The method and a spreadsheet template are on the economics of agent-built software. - Keep the gates unchanged. A model or effort downgrade ships only if the same CI gates (tests, type checks, lint, review agents) pass at the same rate. Run the change on one pilot team for two weeks first, and compare its revert rate and CI failure rate with the previous period.
- Re-run your evals before a policy change. When a new model ships or you lower
maxEffortLevel, follow the new-model evaluation playbook instead of switching on a price table. - Name the owners. The tech lead owns the model-and-effort policy and the pilot comparison. Finance owns the spend limits. The platform team owns the telemetry pipeline and the managed-settings file.
When Claude Code cost controls break down
Section titled “When Claude Code cost controls break down”/usagesays pennies, the invoice says thousands. On a subscription, the session figure is not your bill. On the API, the spend is often CI keys that never run interactively, or other machines that/usagecannot see. Reconcile against Console workspace reporting or the org spend report, per key and per user.- The dollar figures do not match the contract. Claude Code reports list price. Set
modelPricingin managed settings, then confirm theat your organization's configured ratesnote in/usage. - Telemetry never arrives. Check that
CLAUDE_CODE_ENABLE_TELEMETRY=1and an exporter are both set, and that eachotlpexporter has a protocol. Metrics export every 60 seconds by default. Startclaudewith--debug-file ./otel.logand search the log for[3P telemetry]. - Anthropic’s dashboards are empty on Bedrock, Google Cloud or Foundry. That is expected: Claude Code does not send cloud-provider usage back to Anthropic. Use OpenTelemetry or a gateway.
- The metrics bill exceeds the Claude bill. Every resource attribute, plus the default
session.idand account labels, multiplies the series count. SetOTEL_METRICS_INCLUDE_SESSION_ID=false, keep resource attributes low-cardinality, or setOTEL_METRICS_INCLUDE_RESOURCE_ATTRIBUTES=falseto keep them out of datapoint labels. - MCP context jumped after moving behind a gateway. When
ANTHROPIC_BASE_URLpoints to a non-first-party host, Claude Code falls back to loading MCP tools upfront. If your gateway forwardstool_referenceblocks, setENABLE_TOOL_SEARCH=true. - The model allowlist does nothing. It sits in a lower-ranked managed source than the one Claude Code reads, or
enforceAvailableModelsis missing and people pick Default. Run/statusto see which settings source applied. - A session spends money while nobody types. A
/loop, a goal waiting on background work, or a message from another session starts new turns with the full context. Cancel the loop, or setcrossSessionInboundtohold. - Rate limits bite during a training day. Anthropic’s rate-limit recommendations (checked 2026-09-26) assume normal concurrency: 15k–20k tokens per minute per user for 100–500 users, more for small teams. Raise the organization limit for the event, or stagger the sessions.
- A downgrade quietly raised rework. Cost per accepted change went up while spend went down. Roll the policy back for that team and re-run the evals before you try again.
Where to go next with Claude Code cost control
Section titled “Where to go next with Claude Code cost control”- Performance optimization: token-level tactics for one session
- AI usage cost governance: budgets, attribution and a review cadence for the whole organization
- Agent observability: the full telemetry catalog, traces and a reference dashboard
- LLM gateway: per-key spend tracking and hard limits on cloud providers
- Cost per context across tools: the same levers in Codex and Cursor