Skip to content

[Feature]: add provider/model estimated cost and cache metrics to Usage #1820

Closed

Description

@str0203

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.jsonl directly 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:

  1. Normalize and expose provider/model cache and pricing fields in the usage-summary/API result.
  2. Add aggregation and regression tests.
  3. Add provider/model tables and estimated-cost columns.
  4. 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

  1. coderabbitai commented on Aug 16, 2026

    @coderabbitai
    Contributor
    🔗 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 plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  2. Ingwannu commented on Aug 17, 2026

    @Ingwannu
    Owner

    This is useful, but current dev already 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.ts and the Usage/provider surfaces:

    • provider/model request and token attribution;
    • top-level cache-read and cache-creation token totals;
    • coverage ratio;
    • per-request, per-model, and per-provider estimated cost;
    • explicit unpriced/unmetered request counts;
    • calendar-day buckets with model attribution.

    The remaining concrete gap is narrower:

    1. carry cache-read/cache-creation counters into each provider/model row, not only the top-level totals;
    2. expose per-row priced/unpriced or coverage state instead of omitting estimatedCostUsd without an explicit reason;
    3. define one cache-hit formula and return null/unknown when its inputs were not reported;
    4. enrich daily rows with the same token/cache/cost fields so a day drill-down does not reconstruct them in the frontend;
    5. then add the provider/model/day UI using only that API result.

    Please keep #1058 as the date-range interaction dependency. I would accept this in backend-first slices with deterministic summary tests; parsing usage.jsonl or recomputing accounting in React would be a blocker.

  3. lidge-jun commented on Aug 19, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 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이 작성했습니다

  4. lidge-jun commented on Aug 19, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 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이 작성했습니다

  5. alexph-dev commented on Aug 21, 2026

    @alexph-dev
    Contributor

    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:

    • GPT-5.6 Sol stayed fixed at 29,184 cache-read while input grew 57,063 → 57,178 → 57,765 (about 50–51% read).
    • Claude Opus 5 stayed fixed at 45,478 cache-read while recreating 38,766 → 38,958 cache-write tokens on consecutive turns.
    • Same-day Codex Desktop controls were materially healthier: main Sol conversations aggregated 78.9–93.1% cache-read; one Claude Fable conversation aggregated 93.2% over 18 requests.

    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:

    1. cache-read share;
    2. cache-creation/write share;
    3. a warning/filter for repeated follow-up requests in the same conversation where read tokens stay fixed and write/uncached input remains large;
    4. cold-first-turn exclusion or an explicit first-turn dimension, so expected cold misses do not hide continuation regressions.

    The authoritative raw counters already exist in the usage rows; this should remain a summary/API calculation rather than frontend log parsing.

  6. Ingwannu commented on Aug 21, 2026

    @Ingwannu
    Owner

    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.

  7. added 8 commits that reference this issue on Aug 22, 2026
    8b4aa95
    d2e7920
    5072f07
    1500d2b
    1256544
    9441c8e
    71cd4ca
    b816aca
  8. 17 remaining items

  9. added 9 commits that reference this issue on Aug 29, 2026
    a0aaf6a
    b5646ce
    1408cfa
    c32af52
    de3c514
    12e605c
    0411a8b
    90c2da9
    7071b2d
  10. added a commit that references this issue on Sep 14, 2026
    fa4aff2
  11. added a commit that references this issue on Sep 17, 2026
    23c6a0e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions