Chapter 05 · Section V · 10 min read
5.5 Monitoring: usage tracking, cost, analytics
How to know what Claude Code is doing across a fleet — usage and cost telemetry, per-user attribution, and the metrics worth alerting on.
Once Claude Code is in many hands, three questions come up on rotation: how much is this costing us, who is using it well, and what should we alert on. This section is the shortest useful answer to each.
Where usage data comes from
Three sources, from most to least detailed:
- OTLP telemetry — if you enabled it in managed settings (Section 5.4). Per-session, per-tool, per-model, with cost.
- Provider billing — Anthropic console, Bedrock Cost Explorer, Vertex billing. Aggregate; delayed by hours.
- Local session logs — what each machine wrote out. Useful for debugging one user; not great for fleet views.
For fleet observability, OTLP is the answer. Everything else is fallback.
The metrics worth tracking
Small set that covers 90% of what a platform team needs:
| Metric | Why |
|---|---|
| Cost per user per week | Fair-use ceiling; anomaly detection |
| Cost per repo per week | Which projects use it most |
| Sessions per user per day | Engagement signal |
| Tool call mix (Read vs Edit vs Bash) | Are people using the loop, or just chatting? |
| Permission denials per user | Sign of misconfiguration or attempted misuse |
| Model distribution | Are people picking sensibly? Overusing Opus? |
| Fallback activations | Rate-limit or reliability issue |
Dashboards on cost + denials are the ones people actually look at. Everything else is for investigations.
Per-user attribution
Set CLAUDE_USER (or the equivalent env you standardise on) at session start:
export CLAUDE_USER="$(id -un)@$(hostname)"
Telemetry then tags every event with the user. Without this, everything is anonymous — fine for aggregate cost, useless for anomaly detection.
Alerts
Two alerts pay for themselves; more than that is noise.
- Cost spike per user. “User X spent 10× their weekly average today.” Usually a scripted loop that forgot to exit; occasionally a leaked credential.
- Repeated permission denials. “User X hit 20+ denials in an hour.” Either their allowlist is misconfigured or they are probing for a bypass — both worth a look.
Set thresholds by observed norm, not absolute values. A ten-user team’s “high” is different from a hundred-user team’s.
Cost containment
If cost is genuinely a concern, the levers in order of impact:
- Model default. Set
modelto Sonnet in managed settings; make Opus opt-in. - Thinking budget cap. Cap
max_thinking_tokenscentrally. - Rate limit per user. A
PreToolUsehook that tracks per-user QPM. - Deny WebSearch. Cheap tool per call, but people love it and it adds up.
Check your understanding
Quick check
—