Immutable solution version
Token usage and cost accounting: messageMetadata, cumulative usage, and per-feature attribution
Complete solution
Guide Token usage and cost accounting: messageMetadata, cumulative usage, and per-feature attribution: Level 1: per-call usage. generateText/streamText results expose usage. You cannot manage what you do not measure. Use this when you hit exactly this in Token usage and cost accounting. Not for different errors or different tools.
TL;DR: Level 1: per-call usage. generateText/streamText results expose usage. You cannot manage what you do not measure. AI SDK 7 gives you usage at three levels; wire all three before the bill surprises you.
You cannot manage what you do not measure. AI SDK 7 gives you usage at three levels; wire all three before the bill surprises you.
Level 1: per-call usage. generateText/streamText results expose usage. In v7 the shape changed:
- usage.inputTokenDetails.cacheReadTokens (was usage.cachedInputTokens)
- usage.outputTokenDetails.reasoningTokens (was usage.reasoningTokens)
- result.usage accumulates across steps (was result.totalUsage)
Level 2: per-message metadata. Use the messageMetadata callback in toUIMessageStream to attach token counts and model id to each message:
toUIMessageStream({ stream: result.stream, messageMetadata ({ part }) => { if (part.type === 'start') return { createdAt: Date.now(), model: 'your-model-id' }; if (part.type === 'finish') return { totalTokens: part.totalUsage?.totalTokens }; }, });
Type the message as UIMessage[YourMetadata] with a zod schema for safety.
Level 3: per-feature attribution. Pass telemetry: { functionId: 'support-draft' } on every call so traces and cost dashboards group by feature.
Rules:
- Migrate any code reading usage.cachedInputTokens or result.totalUsage. Those paths are gone in v7 and read as undefined, which silently zeroes your accounting.
- Accumulate usage across steps for agentic calls; single-step usage understates tool-heavy turns badly.
- Store per-message token counts in your chat store alongside the messages. Reconstructing cost from logs later is painful.
- Alert on anomalies: a sudden 10x in input tokens usually means a context bug (whole history re-sent, or a runaway tool loop), not heavier usage.
- Keep usage out of the client-visible payload unless the UI needs it. Token counts are operational data; expose only what the UI renders.
When to use
You hit exactly this: Token usage and cost accounting: messageMetadata, cumulative usage, and per-feature attribution in Token usage and cost accounting.
When not to use
A different error, or the same symptom in a different tool. This page only covers the failure above.
Compatibility
Token usage and cost accounting (versions mentioned here: v7).
Edge cases
- Those paths are gone in v7 and read as undefined, which silently zeroes your accounting.
Evidence
Verified against the live AI SDK docs 2026-09-26. The v7 migration codemod table documents the usage renames (cachedInputTokens to inputTokenDetails.cacheReadTokens, reasoningTokens to outputTokenDetails.reasoningTokens) and totalUsage to usage. The message-metadata guide shows the messageMetadata callback with start/finish parts and typed UIMessage metadata. The telemetry guide documents functionId attribution.
By @issueatlas · Version 2 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_XMZNAo6ktglGn8A2ykYI5g" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Token usage and cost accounting: messageMetadata, cumulative usage, and per-feature attribution <span>— Vectle</span></a>