@bickov — your closing question (“does per-request usage even split cached vs fresh input?”) is the right one, and I can answer the provider half of it: the split exists at the source, but the two big vendors disagree about what “input tokens” means. Anthropic reports three separate fields — input_tokens, cache_read_input_tokens, cache_creation_input_tokens — where input_tokens is the uncached remainder only (total prompt = sum of all three). OpenAI reports prompt_tokens including cached, with the cached portion broken out under prompt_tokens_details.cached_tokens. Whether Cursor’s SDK surfaces those raw fields is a question for @deanrie — but if you can get the raw provider usage object anywhere in the pipeline, record it whole, because anything that aggregates “input tokens” across providers without normalizing is comparing different quantities.
And your instinct that a caching artifact can impersonate a tool effect — we have a measured example of exactly that, in both directions:
The bill 6×'d with zero behavior change. A routine 4-call agent session in our editor read only 4,329 of 98,741 input tokens from cache (4% hit rate on a workload that should sit ~95%) and re-wrote 94,404 tokens — $0.59 of the session’s $0.60 was cache writes. The cause was an internal history-trimming detail that shifted the byte prefix every iteration, invalidating the cache on every call. No model, tool, or prompt changed. Fixing it (trim with hysteresis so persists stay append-only) was an honest 6× cost cut ($0.60 → ~$0.10) that any tool-attribution benchmark running during that window would have credited to the wrong thing. Without the cache-read/cache-write/fresh split in the per-run record, this is invisible — it’s just “input tokens moved.”
@deanrie — fully agree on measured vs estimated buckets, and I’d add two hard-won refinements:
-
“Estimated” needs a reconciliation step, not just a label. Our own in-app cost estimate read ~$25 for a session the provider’s console billed at ~$3.40 — a blended per-token rate ignoring that output is ~5× input and a cache read is ~10% of input. Confidently wrong by 7×, no error anywhere. The fix that stuck wasn’t just per-token-type pricing; it was a locked test that replays a real observed session (615k in / 19k out / 141k cache-read / 474k cache-write) and asserts it prices to the console number. An estimate that’s never been checked against a real invoice is “unverified,” not “estimated.”
-
The wiring check needs a sibling: a meter check. Our gateway silently dropped the provider’s usage field for months — every cost surface read zero while the persistence layer tested perfectly in isolation. During that window, any savings measurement would have been spectacular, because a broken meter is indistinguishable from a perfectly efficient tool. So alongside “measured config reaches the shipped path,” I’d gate on “usage is provider-reported, present, and non-zero — missing usage invalidates the run rather than counting as cheap.”
On the coupling point (usage and pass rate together, never usage alone): agreed, and our sharpest evidence is the inverse case. Our fine-tune’s real win showed up entirely in the outcome column — apply-rate +22 points, leak-checked — while its token delta was noise-level (~1%), a number we deliberately don’t claim. A usage-only record would have called the whole thing a wash.
On new numbers: our measured record (the n≥5, tier-stratified results from the earlier post) stands as published, and we’re not running new sweeps at the moment — I think the most useful next data point is @yohjisakamoto 's re-run with the gates in place, against Cursor’s actual measured/estimated surfaces. Happy to compare methodology when those land.
Full writeup of the metering side, with the changelog receipts: Three ways a token meter lies (and what it took to make ours honest)…
Okay hope this helps, will need to be head down remainder of day. Cheers.