Skip to content

Fix: price current Claude models and 1-hour cache writes in usage dashboard - #489

Open
anascherif wants to merge 1 commit into
winfunc:mainfrom
anascherif:fix/usage-cost-current-models
Open

anascherif wants to merge 1 commit into
winfunc:mainfrom
anascherif:fix/usage-cost-current-models

Conversation

@anascherif

Copy link
Copy Markdown

Problem

The Usage Dashboard calculates cost in calculate_cost (src-tauri/src/commands/usage.rs), and that function only knows two model families. It matches on substrings:

  • any model containing opus-4 gets Opus 4's $15 / $75;
  • any model containing sonnet-4 gets $3 / $15;
  • every other model gets $0.

So, with current Claude Code models:

  • Opus 4.5 to 4.8 ($5 / $25) are charged at the Opus 4 rate, 3x too much.
  • Opus 5 / 5.5, Sonnet 5 / 5.5, Haiku 4.5 / 5.5 and Fable show $0.
  • Cache writes are all charged at the 5-minute rate (1.25x input). Claude Code writes to the 1-hour cache, which is billed at 2x input. Its transcripts report the split in usage.cache_creation.ephemeral_1h_input_tokens.

On my own Claude Code history, the dashboard total was $1,168. With this change it is $736:

Model Before After
claude-opus-4-8 $1,168.20 $424.57
claude-opus-5-5 $0.00 $278.98
claude-fable-5-2 $0.00 $30.64
claude-haiku-4-5-20251001 $0.00 $0.70
claude-sonnet-5 $0.00 $0.49
claude-haiku-5-5 $0.00 $0.18

Approach

  • model_pricing() reads the family and version out of the model ID and looks them up in a price table. It handles:

    • newer IDs (claude-opus-4-8);
    • dated snapshots (claude-sonnet-4-5-20250929);
    • the older naming (claude-3-5-haiku-20241022);
    • Bedrock IDs (us.anthropic.claude-opus-4-1-20250805-v1:0).

    The table lists input, output and cache-read prices. Cache-write prices follow Anthropic's multipliers: 1.25x input for 5 minutes, 2x for 1 hour.

  • UsageData reads cache_creation.ephemeral_1h_input_tokens. calculate_cost charges that share at the 1-hour rate and the rest at the 5-minute rate. The 1-hour share is capped at cache_creation_input_tokens. Entries without the split are priced as before.

  • Unknown models (for example <synthetic>) still cost $0, as before.

Testing

Added unit tests in usage.rs for:

  • the price of each model generation;
  • unknown models;
  • 1-hour, mixed and 5-minute cache writes;
  • a missing split;
  • a 1-hour count larger than the cache writes;
  • a row with every kind of token.

I don't have the Tauri build dependencies on this machine. So I ran these tests (6 passed) and cargo clippy (clean) on calculate_cost, model_pricing and the tests copied into a standalone crate. rustfmt --check on usage.rs is clean.

Side effects and limitations

  • The price table needs a new entry when Anthropic releases a new model, as the old constants did. Until then, a new model shows $0, as unknown models do today.
  • Long-context (over 200K tokens) premium pricing is not modelled, as before.

…hboard

The usage dashboard priced any model containing "opus-4" at Opus 4's
$15/$75, any containing "sonnet-4" at $3/$15, and every other model at $0.
So Opus 4.5-4.8 were charged 3x their real price, and Haiku 4.5/5.5,
Opus 5/5.5, Sonnet 5/5.5 and Fable showed no cost at all. It also priced
every cache write at the 5-minute rate (1.25x input), but Claude Code
writes to the 1-hour cache, billed at 2x input, and its transcripts
report the split in usage.cache_creation.

Price each model by its family and version, and bill the 1-hour share of
the cache writes at the 1-hour rate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant