Repository navigation
[Feature]: add provider/model estimated cost and cache metrics to Usage #1820
Description
Area
Web Dashboard → Usage
Relationship to existing work
This is a focused follow-up to #1058.
Issue #1058 tracks calendar-day/custom-range filtering and daily model breakdown. This issue tracks the provider/model usage accounting that should be displayed for the selected timeframe. It should reuse the existing usage-summary/data path and pricing infrastructure rather than introduce a separate analytics system.
Goal
Give operators a practical local estimate of where tokens and estimated spend are going, and how effectively prompt caching is being used.
This is intentionally about local estimated usage cost, not official provider billing, account balances, invoices, or quota tracking.
Required breakdown
For the selected calendar day or date range, show provider-level and model-level rows containing, where available:
- provider
- model
- request count
- input tokens
- output tokens
- total tokens
- cache-read input tokens
- cache-creation input tokens
- estimated cost in USD
- usage/price coverage or an equivalent indication of data quality
Model rows must remain attributable to their provider. The provider view should support expanding into, or filtering by, its models.
Cache metrics
Where the upstream/provider reports sufficient counters, expose:
- cache-read tokens
- cache-creation tokens
- cache hit rate
- optionally, cache participation rate if that is more meaningful for a provider
The cache-hit-rate formula must be deterministic and documented. A reasonable default is:
cacheReadInputTokens / inputTokens
or, when uncached input is available:
cacheReadInputTokens / (cacheReadInputTokens + uncachedInputTokens)
If the necessary counters are unavailable, show unavailable/unknown, not 0%.
Estimated cost
- Reuse the existing model/provider pricing and cost-estimation fields where possible.
- Include cache-read and cache-creation pricing when configured and supported.
- If a provider/model has no matching price, show the row as unpriced/unavailable instead of silently treating it as $0.
- Keep the result clearly labeled as an estimate.
Daily drill-down
When a date range contains multiple days, users should be able to inspect the same provider/model/token/cache/cost breakdown for one individual calendar day, either by selecting a day in the existing Usage chart or through a daily detail table.
The implementation should compose with #1058's date filters and daily model view, but does not need to duplicate that UI.
Data-path requirements
- Aggregate in the authoritative usage-summary/API layer.
- Do not parse
usage.jsonldirectly in the frontend. - Do not reconstruct provider/model totals from chart pixels or unrelated UI state.
- Preserve existing 7d/30d/available-history behavior and the date semantics defined by [Feature]: add single-day/custom date filtering and daily model metrics to Usage #1058.
- Add deterministic tests for provider/model attribution, cache counters, cache-rate calculation, estimated pricing, and unavailable-data behavior.
Suggested delivery
This can be delivered in small independently testable slices:
- Normalize and expose provider/model cache and pricing fields in the usage-summary/API result.
- Add aggregation and regression tests.
- Add provider/model tables and estimated-cost columns.
- Add cache metrics and daily drill-down integration.
Acceptance criteria
- A selected day or date range shows provider-level and model-level request/token totals.
- Cache-read and cache-creation tokens are shown separately when available.
- Cache hit rate is shown only when its inputs are available, using a documented formula.
- Missing cache data is shown as unavailable/unknown, not as zero.
- Estimated cost is shown per provider/model when price data is available.
- Cache pricing is included when supported by the configured price data.
- Unmatched prices are visibly unpriced/unavailable, not silently counted as $0.
- A user can inspect the provider/model breakdown for an individual day within a multi-day selection.
- Existing Usage ranges and [Feature]: add single-day/custom date filtering and daily model metrics to Usage #1058's date-boundary/API separation requirements remain intact.
- Backend/API and frontend regression tests cover the new behavior.
Out of scope
- Official provider invoices or billing APIs
- Provider account balances or quota/reset tracking
- A separate analytics database
- Replacing the existing Usage workspace
Activity
coderabbitai commentedon Aug 16, 2026
🔗 Related PRs
#501 - fix(usage): keep large dashboard logs responsive [merged]
#1010 - feat(usage): user-configurable per-model cost overlay (providers..modelCosts) [merged]
#1079 - feat(usage): add date filters and daily model breakdown in dashboard (
#1058) [open]#1083 - feat(usage): add account usage filter and indicators in provider workspace (
#1063) [open]#1638 - fix(usage): align 7d and 30d range windows to start-of-day calendar boundaries (
#1580) [open]📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
Ingwannu commentedon Aug 17, 2026
This is useful, but current
devalready implements a substantial part of the requested backend contract, so it should be treated as a focused completion issue rather than a new analytics subsystem.Already present in
src/usage/summary.tsand the Usage/provider surfaces:The remaining concrete gap is narrower:
estimatedCostUsdwithout an explicit reason;null/unknown when its inputs were not reported;Please keep #1058 as the date-range interaction dependency. I would accept this in backend-first slices with deterministic summary tests; parsing
usage.jsonlor recomputing accounting in React would be a blocker.lidge-jun commentedon Aug 19, 2026
리뷰 · 우선순위 36 / 80
Usage 화면에서 선택한 날짜나 기간에 대해, 프로바이더/모델별로 토큰과 추정 비용, 캐시 사용량을 보고 싶다는 요청입니다. 공식 청구서나 잔액이 아니라 로컬 추정만 다루고, #1058의 날짜 필터와 기존 usage-summary/가격 경로를 재사용하자는 범위입니다.
현재
dev의src/usage/summary.ts에는 이미 합계용cacheReadInputTokens,cacheCreationInputTokens,estimatedCostUsd,pricedRequests,unpricedRequests가 있습니다.UsageAccount에도 캐시 카운터와priceCoverageRatio가 있습니다. 다만UsageModel과UsageProvider행은estimatedCostUsd와 토큰 합은 있어도 캐시 읽기/생성, 캐시 적중률, 가격 커버리지 표시가 행 단위로 빠져 있습니다.UsageDayModel도 요청 수와 토큰만 있어 일별 드릴다운에 캐시/비용이 붙지 않습니다.프론트에서
usage.jsonl을 직접 파싱하거나 차트 픽셀로 합계를 다시 만들지 말라는 조건은 현재 구조와 맞습니다. 집계는src/usage/summary.ts와src/server/management/logs-usage-routes.ts,src/usage/cost.ts의estimateRequestCost쪽에 두는 게 맞습니다. 가격이 없는 행을 $0으로 넣지 말고 unpriced/unavailable로 두는 규칙도, 합계가 이미 unmatched price를 제외하는 방향과 같습니다.해결방안: usage-summary API에 프로바이더/모델 행의 캐시 카운터와 추정 비용, 커버리지 필드를 먼저 정규화해 노출하고, 캐시 적중률은
cacheReadInputTokens / inputTokens처럼 문서화된 공식만 쓰며 입력이 없으면0%가 아니라 unavailable로 표시하면 됩니다. UI 테이블과 일별 드릴다운은 그 API 위에 올리면 됩니다. 공식 빌링 API나 별도 분석 DB는 이 이슈 범위가 아닙니다.이 댓글은 grok-bot이 작성했습니다
lidge-jun commentedon Aug 19, 2026
리뷰 · 우선순위 56 / 80 · 유지
점수 정정임. 36 → 56. Usage에 프로바이더/모델별 예상 비용이랑 캐시(cache-read/create)를 보여 달라는 요청. 청구서/잔고가 아니라 로컬 추정. #1058 날짜 필터 후속이고, 기존 usage-summary/가격 인프라를 재사용하면 됨.
열어 둠. 가격 넣는 방향(#1299 쪽)이랑 맞아서 우선순위를 올림. 별도 분석 시스템을 새로 깔 필요는 없음. 공짜 배지는 안 넣음.
해결방안: 선택 기간에 provider/model 행으로 request, in/out/total tokens, cache-read, cache-create, USD 추정, coverage. #1058 데이터 경로 재사용.
이 댓글은 grok-bot이 작성했습니다
alexph-dev commentedon Aug 21, 2026
Operator evidence: cache-write churn needs to be visible per provider/model/session
A 2026-08-20 audit on OpenCodex 2.27.0 found a quota-impacting pattern that the current Logs table exposes per request but the Usage aggregation makes hard to detect.
In one continued Claude Desktop session:
This is why the requested provider/model cache-read and cache-creation columns are operationally important. Cache-read rate alone is insufficient for Anthropic: a row can show a 54% read rate while also rewriting ~46% of the prompt every turn.
For the scoped completion of this issue, please consider exposing or deriving:
The authoritative raw counters already exist in the usage rows; this should remain a summary/API calculation rather than frontend log parsing.
Ingwannu commentedon Aug 21, 2026
Thank you; this evidence materially strengthens the need for row-level cache accounting. The current summary still exposes cache read/create only at the top level and account rows, while provider/model/day rows lack both counters and an explicit unknown/coverage state.
I would keep items 1 and 2 in this issue: provider/model/day rows should expose cacheReadInputTokens, cacheCreationInputTokens, deterministic read/write shares, and null when the upstream did not report the required inputs. The Anthropic example is exactly why cache-read share alone is insufficient.
Items 3 and 4 need a separate conversation-series contract rather than being inferred from aggregate rows. Persisted usage does carry a best-effort bounded conversationId, but it can be absent and its first observed request is not necessarily the real cold first turn. A warning must therefore require a stable conversation id, at least two measured follow-ups, identical provider/model attribution, and explicit reported cache counters; otherwise it must remain unknown. It must not label ordinary cold starts or cross-provider switches as churn.
I am keeping this issue focused on the backend-first per-row fields and UI. Once those fields land, a small follow-up can define the conversation-level churn detector with its own false-positive regressions instead of burying that policy inside the dashboard.
feat(usage): add provider, model, and day cache metrics with price co…
feat(usage): add provider, model, and day cache metrics with price co…
fix(usage): deduplicate priced request identity and populate daily mo…
fix(usage): return null cacheHitRate when cache counters are unobserv…
feat(usage): add provider, model, and day cache metrics with price co…
fix(usage): deduplicate priced request identity and populate daily mo…
fix(usage): return null cacheHitRate when cache counters are unobserv…
fix(usage): address review feedback on cache metrics and combo cost a…
17 remaining items
fix(usage): deduplicate priced request identity and populate daily mo…
fix(usage): return null cacheHitRate when cache counters are unobserv…
fix(usage): address review feedback on cache metrics and combo cost a…
feat(usage): add provider, model, and day cache metrics with price co…
fix(usage): deduplicate priced request identity and populate daily mo…
fix(usage): return null cacheHitRate when cache counters are unobserv…
fix(usage): address review feedback on cache metrics and combo cost a…
feat(usage): add provider, model, and day cache metrics with price co…
fix(usage): deduplicate priced request identity and populate daily mo…
fix(usage): return null cacheHitRate when cache counters are unobserv…
fix(usage): address review feedback on cache metrics and combo cost a…
feat(usage): add provider, model, and day cache metrics with price co…
feat(usage): add provider, model, and day cache metrics with price co…
feat(usage): add provider, model, and day cache metrics with price co…