CClawMetryDocs

Cost & usage

Attribution#

A total is not an answer. "We spent $840 last month" starts a conversation; "$610 of it was one nightly job re-reading the same repository" ends one.

The axes#

AxisAnswers
RuntimeWhich tool is expensive
ModelWhich model is expensive
SessionWhich individual runs are expensive
AgentWhich of your agents is expensive
SkillWhich capability drives spend
ToolWhich tools are called most, and cost most
PluginPer-plugin usage, where a runtime attributes it
TeamRolled up for chargeback
bash
curl -s localhost:8900/api/token-attribution | jq
curl -s localhost:8900/api/usage/by-plugin | jq
curl -s localhost:8900/api/local/runtimes | jq '.rows'
curl -s localhost:8900/api/local/models | jq '.rows'

Team mappings#

Map a key or an agent to a team, and the rollups follow:

bash
curl -s localhost:8900/api/usage/team-mappings -X POST \
  -H 'content-type: application/json' \
  -d '{"key_type":"agent","key_value":"nightly-refactor","team":"platform"}'

curl -s -X DELETE localhost:8900/api/usage/team-mappings/agent/nightly-refactor

This is what makes an internal chargeback conversation possible without anyone hand-maintaining a spreadsheet.

Sub-agents: the double-counting rules#

Delegation is where attribution gets genuinely hard, and where most tools get it wrong. ClawMetry's rule is that a child's spend belongs to the child, and the parent is not billed for it twice.

How that is achieved differs per runtime, because they persist delegation differently:

Copilot stamps every sub-agent API call with initiator='sub-agent' and the parent tool-call id, so child spend is split out of the parent rollup rather than added to it. That is vendor-billed truth.

OpenHands stores a copy of each child's metrics under a delegate:* key on the parent. Summing every key and also listing the child would count it twice, so those keys are excluded from the parent row.

Deep Agents children carry their own usage_metadata and the parent's usage does not include them, so per-child tokens never double-count.

Antigravity children have their own token rows, so nothing is double-counted against the parent.

QM keeps no per-child token split at all — child spend lands in the parent turn. Children are therefore reported with zero tokens and cost unavailable, rather than an invented split.

Pi and PicoClaw persist no child transcript. Children are synthesised from the parent's tool call and result; Pi's carry the embedded per-child usage, PicoClaw's carry nothing because nothing exists.

The general rule when you are reading a delegation tree: if a child shows unavailable, that is the honest state, not a bug. Adding it into the parent would be the bug.

Branches and abandoned work#

Pi, Devin and Deep Agents store conversations as trees. A /fork or /revert leaves the abandoned turns in place as sibling branches.

Summing every row bills you for work that was thrown away. ClawMetry walks the active chain — from the session's main chain pointer back through parents to the root — and reports the abandoned nodes as a count.

So a Devin session's cost is what the surviving conversation cost. If you want to know what the abandoned branches cost, that count is in the session's extra data, and it is often the more interesting number.

Cross-runtime comparison#

Cost is comparable across runtimes because everything goes through one derivation path, and vendor dollars are used where they exist.

What is not comparable is a runtime that records nothing. PicoClaw and Cursor-on-a-laptop show as unknown. A ranking that silently treats those as zero would flatter them, so any comparison worth trusting states which runtimes it had data for.

Cross-runtime questions

Deriving cost per unit of work#

The question behind most attribution work is not "what did it cost" but "what did we get". ClawMetry does not decide what counts as a durable result, but it gives you the inputs:

  • Sessions that ended with no file change — the no_progress detector's domain
  • Sessions that ended in an error
  • Sessions that were stopped or killed
  • Session outcome, where a runtime records one
bash
curl -s localhost:8900/api/local/query -X POST \
  -H 'content-type: application/json' \
  -d '{"shape":"rollup_sessions","args":{"limit":200}}' \
  | jq '[.rows[] | {title, cost_usd, status, stuck}]'

Reducing spend

Cookie preferences