Anthropic has officially confirmed that Claude Code’s local transcript files contain redundant usage data, causing naive cost scripts to report inflated token counts. In issue #87303, closed in August 2026, a maintainer stated that the duplication is intentional and documented, placing the burden of accurate accounting on the consumer. A session analysis revealed that summing every line in a JSONL transcript resulted in a 1.92x overcount of cache creation tokens compared to deduplicating by message ID.

The Mechanics of Duplicate Entries

Claude Code stores sessions as JSONL files where each API response can generate multiple entries. When a single response contains several content blocks—such as a thinking block followed by multiple tool_use calls—the agent writes one assistant entry per block. Each entry carries its own UUID but shares the same message.id and a byte-identical usage object. In the reported session, 521 usage records corresponded to only 323 distinct message IDs, proving that duplicate lines are the norm, not the exception, when parallel tool execution occurs.

Anthropic’s Official Guidance

The Agent SDK’s cost tracking guide explicitly instructs developers to track which message IDs have already been counted and skip duplicates to avoid inflated totals. However, a critical caveat exists for output tokens: the per-step output_tokens value in the transcript is merely a placeholder from the message_start event. The accurate output count is only available in the SDK’s final result message or via the claude -p --output-format json command. Developers relying on transcript sums for real-time billing estimates must trust input and cache deduplication more than output counts.

Hidden Pitfalls in Cost Accounting

Beyond simple line duplication, other factors contribute to erroneous totals. Branching commands like /branch or --fork-session create new transcripts that copy the entire conversation history, meaning summed project folders double-count shared history. Additionally, resumed sessions automatically include prior spend in their result totals, so summing multiple result objects leads to double-counting. Issue #64880 also highlights a rare edge case where server load causes sequential responses to share a message ID, requiring deduplication keys that include requestId for absolute accuracy.

Key Takeaways

  • Deduplicate by message.id: Always group transcript entries by message ID before summing input and cache tokens to avoid ~2x overcounts.
  • Ignore transcript output_tokens: Use the final result message or claude -p --output-format json for accurate output token counts.
  • Watch for branching artifacts: Summing across multiple session files in a project folder double-counts history if not deduplicated globally.
  • Verify with official APIs: Transcript sums are estimates; use the Usage and Cost API or Console for billing-grade figures.

The Bottom Line

This isn't a bug in the model, it's a trap for the lazy developer. If your cost dashboard is climbing while your agent sits idle, you are likely counting duplicate transcript lines. Deduplicate by message ID or trust the final result object, because the raw JSONL is a stream of events, not a ledger of costs.