Stats & Usage drops OpenCode cache tokens, under-reporting OpenCode usage ~70x
- Dominant language
- TypeScript
- Stars
- 71.3k
- Forks
- 4.7k
- Avg merge
- 14h 54m
- Merged PRs (30d)
- 520
Description
## Describe the bug
Stats & Usage under-reports OpenCode by roughly 70x, so OpenCode-heavy days render as empty cells on the "Daily intensity" heatmap and OpenCode barely registers in "Total tokens", even on days with hundreds of millions of tokens of OpenCode activity.
Cause: the OpenCode scanner reads `opencode.db` with the wrong token model. In OpenCode's schema `tokens.input` is **uncached** input only and `tokens.total = input + output + reasoning + cache.read + cache.write` (verified on 99,153 assistant messages: zero rows where `total` differs from that sum). Two places in `src/main/opencode-usage/` assume the opposite:
1. `selectSessionUsageRows` (the fast path used whenever the DB has materialized `session.tokens_*` columns) synthesizes `total: tokens_input + tokens_output + tokens_reasoning`, dropping `tokens_cache_read` and `tokens_cache_write` entirely.
2. `parseOpenCodeUsageRow` sets `cachedInputTokens = min(cache.read, input)`, which is ≈ `input` on real data (e.g. `input: 638`, `cache.read: 642944`), so "new input" collapses to ~0 and cache share is meaningless.
Because prompt caching means cache reads are ~97% of OpenCode traffic, the fast path discards almost everything.
## Steps to reproduce
1. Use OpenCode for a while with a provider that reports cache reads (any recent OpenCode; `session.tokens_*` columns exist since the `20260510033149_session_usage` migration).
2. Open Stats & Usage in Orca with OpenCode analytics enabled.
3. Compare the OpenCode total with `SELECT SUM(tokens_input+tokens_output+tokens_reasoning+tokens_cache_read+tokens_cache_write) FROM session` in `~/.local/share/opencode/opencode.db`.
On my machine (Orca 1.4.197, macOS, 5.4 GB `opencode.db`):
| | Orca reports | opencode.db |
|---|---|---|
| All-time OpenCode tokens | 350,043,216 | 24,686,009,276 |
| 2026-08-13 | 7,303,115 | 1,261,349,924 |
| 2026-08-10 | 22,171,623 | 644,128,839 |
Orca's per-day numbers equal `SUM(tokens_input+tokens_output+tokens_reasoning)` exactly, confirming the dropped cache columns.
## Expected behavior
OpenCode totals match OpenCode's own `tokens.total`, and the materialized-session fast path produces the same numbers as parsing the per-message rows it summarizes.
## Environment
- Orca 1.4.197 (macOS 26.3, Apple Silicon)
- OpenCode with `session.tokens_*` columns (schema migration `20260510033149_session_usage`)
Contributor guide
Research direction
Read the scanner code under src/main/opencode-usage/, especially selectSessionUsageRows and parseOpenCodeUsageRow. Reproduce the discrepancy by comparing Orca's totals with the provided SUM query against opencode.db. Done means the materialized-session fast path includes cache reads and writes and matches OpenCode's tokens.total and the per-message parsing path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sqlite, typescript
- Domain
- analytics, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100