Skip to content

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 /usage and /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 -p job 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

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 setupSee spendCap spendPer-user numbers
Claude for Teams or EnterpriseSpend 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 > UsageSpend report CSV; Enterprise Analytics API on Enterprise
Claude Console (API)Console usage page and the auto-created “Claude Code” workspaceWorkspace spend limit, plus a workspace rate limitConsole dashboard; Claude Code Analytics API
Amazon Bedrock, Google Cloud’s Agent Platform (formerly Vertex AI), Microsoft FoundryYour cloud billing consoleYour cloud’s budget controls, or per-user spend limits on a self-hosted Claude apps gatewayOpenTelemetry, the Claude apps gateway, or an LLM gateway such as LiteLLM
Individual Pro or MaxPlan usage bars in /usageMonthly spend limit on usage creditsNot 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”
  1. Read one session with /usage. /usage is the command; /cost and /stats are aliases of it. The Session block shows the session’s dollar figure, a per-model token breakdown and a Prompt 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. Press d or w to 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.

  2. See what fills the context. Run /context for 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 /insights for an HTML report on where recent sessions went wrong (the analysis itself counts against your usage).

  3. 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_PROTOCOL explicitly, because Claude Code has no default protocol. Each key in OTEL_RESOURCE_ATTRIBUTES becomes a label on every metric, so claude_code.cost.usage arrives sliced by department, team and model. OTEL_METRICS_INCLUDE_REPOSITORY (v2.1.269 or later) adds vcs.* repository labels, which answers “which repository drove the spend”. If the collector is reachable from outside a trusted network, add OTEL_EXPORTER_OTLP_HEADERS with a token from your secret store, never a literal in the file.

  4. 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 eventWhat 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.

  5. Report at your contracted rates. Every figure Claude Code shows (/usage, the status line, OpenTelemetry and the --max-budget-usd limit) uses list price unless the modelPricing managed setting says otherwise. Set a multiplier below 1 for a flat discount (above 1 for an internal chargeback markup, v2.1.271 or later), or per-model overrides from 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, the Total cost line in /usage carries the note at your organization's configured rates. The figures are still estimates, not an invoice.

  6. 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:

Terminal window
# 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 latest release channel (v2.1.280 and later), Claude Code defaults to Claude Opus 5.5 at medium effort 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 at medium “matches or exceeds Opus 5 at high”. The stable channel (v2.1.274 on 2026-09-26) still runs older defaults, so check /model before 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"
}
}
  • availableModels restricts which models people can pick, including in subagent frontmatter and CLAUDE_CODE_SUBAGENT_MODEL. This example leaves Fable out; add "fable" for the teams whose evals justify it. On Foundry the opus alias 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 below xhigh makes ultracode unavailable, which is the point for most teams and a real loss for a few.
  • CLAUDE_CODE_SUBAGENT_MODEL sets the model for subagents and workflow agents that are not assigned one another way. A definition’s own model field still wins, so pin model: haiku on custom subagents that only run tests or summarize logs.
  • deniedModels and availableModelsMatch: "exact" (both v2.1.283, latest channel) 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.

The token-level tactics are on performance optimization. These have team-wide impact:

  • /clear between unrelated tasks. It costs nothing and resets the session total. /compact is 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=false loads every definition upfront, and an auto:N threshold loads them upfront while they stay under N% of the context window. Prefer a CLI such as gh over an MCP server where one exists: it adds no tool listing at all.
  • Filter verbose output with a hook. A PreToolUse hook that rewrites npm test to return only failures turns tens of thousands of tokens into hundreds.
  • Move workflow instructions from CLAUDE.md into skills, which load only when invoked.
  • Stop idle spenders. Review the Loops rows in /usage and 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:

  1. Track cost per accepted change. Divide claude_code.cost.usage by 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.
  2. 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.
  3. 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.
  4. 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.
  • /usage says 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 /usage cannot 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 modelPricing in managed settings, then confirm the at your organization's configured rates note in /usage.
  • Telemetry never arrives. Check that CLAUDE_CODE_ENABLE_TELEMETRY=1 and an exporter are both set, and that each otlp exporter has a protocol. Metrics export every 60 seconds by default. Start claude with --debug-file ./otel.log and 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.id and account labels, multiplies the series count. Set OTEL_METRICS_INCLUDE_SESSION_ID=false, keep resource attributes low-cardinality, or set OTEL_METRICS_INCLUDE_RESOURCE_ATTRIBUTES=false to keep them out of datapoint labels.
  • MCP context jumped after moving behind a gateway. When ANTHROPIC_BASE_URL points to a non-first-party host, Claude Code falls back to loading MCP tools upfront. If your gateway forwards tool_reference blocks, set ENABLE_TOOL_SEARCH=true.
  • The model allowlist does nothing. It sits in a lower-ranked managed source than the one Claude Code reads, or enforceAvailableModels is missing and people pick Default. Run /status to 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 set crossSessionInbound to hold.
  • 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”