Decisions
How the numbers are calculated, what is measured and what is deliberately left out, what is stored about whom — and why it was decided that way. Generated from the backend's decision log.
Calculation
How the numbers in the dashboard come about.
Free write tokens are counted
Free write tokens (e.g. OpenAI cache writes) are counted in the dashboard even though they don't directly contribute to cost
Read why → CalculationDerivation of CO₂ factors
See README.md.
Read why → CalculationEphemeral cache tokens: store the undifferentiated remainder as its own value; bill it at the 1h rate
Claude usage reports carry both a flat cache_creation_input_tokens total and, optionally, a split into ephemeral_5m_input_tokens / ephemeral_1h_input_tokens. Sometimes the sum falls short of the …
Read why → CalculationCost stored as cents (BIGINT), CO₂ stored as grams (DOUBLE PRECISION)
Costs and CO₂ are estimates, not billing-grade figures — pricing and CO₂ factors are themselves approximations (see decision 3), and the dashboard's purpose is trend visibility, not exact accounting.
Read why → CalculationMissing price/CO₂ factor defaults to 0, not a distinct "unknown" state
When a model/day has no matching entry in the price or CO₂ factor table (e.g. a new model was used before its price was added), ClaudeUsageIngestService stores costUsdCent/co2Gram as 0 rather than …
Read why → CalculationCost figures are estimates; per-model and total rounding may differ
This applies only to providers that store cost in nano-precision (see decision 12) — currently OpenCode and Copilot, not Claude. For those providers, the total returned by the all-providers endpoint …
Read why → CalculationPer-provider cost precision: whole cents vs. nano-precision
Providers store per-prompt cost at different precisions, and for different reasons — this is not one rule applied three times, it is three separate calls. A shared constraint underlies all three: …
Read why → CalculationCopilot's reasoning_tokens are parsed but not added to output tokens; OpenCode's are
Copilot's ingest payload includes a reasoning_tokens field per prompt, but it is intentionally not added into the stored output-token count. OpenCode's equivalent field is added to its output-token …
Read why → CalculationTotal tokens count input and output only; cache tokens are shown separately
The headline "total tokens" figure — company-wide and per provider — sums input and output tokens. Cache-write and cache-read tokens are excluded from it, but stored and shown separately: in the …
Read why → CalculationCopilot cost is approximated at one US cent per AI unit
Copilot cost is computed as 1 US cent per AI unit, from the AI-unit total the Copilot CLI reports per session (stored as NanoAiu, see decision 12).
Read why →Privacy
What is stored, and what can never be derived from it.
No authentication, no user/team attribution
No authentication; reachable only via VPN. Sender of usage data cannot be traced on the data level. Prompt content is never collected or sent to the backend — only token counts.
Read why → PrivacySeries return number of installations, not users at bucket day
pluginInstallations semantics: number of installations "active" on the bucket day, defined as
Read why →Architecture
How plugins, backend and frontend work together — and which tools are covered.
Plugin-based approach per provider
Claude is the strongest-usage provider, and its subscription plan doesn't expose tokens via API — only pay-as-you-go plans do, which isn't our setup. A plugin architecture handles this and other …
Read why → ArchitectureClaude prices: single source via endpoint, not a duplicated file
The Claude plugin needs the same per-model prices (claude_prices table) as the backend, to show users their own costs. GET /api/prices/claude returns the currently valid price per model family …
Read why → ArchitectureOnly GET routes are versioned (.../v1 suffix); POST ingest and the plugin-facing prices GET are not
The plugins (Claude, Copilot, OpenCode) each live in their own separate repository, one per plugin, since they have fundamentally different data sources and cannot report the same data as each other. …
Read why → ArchitectureCopilot deduplicates on session_id alone — a cross-repo dependency
Copilot's ingest insert uses ON CONFLICT (session_id) DO NOTHING, backed by a unique index on session_id alone. Claude and OpenCode both dedupe on the wider key (session_id, prompt_id).
Read why →