You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #1532 landed on dev and made the bounded read visible to users by exposing the observed snapshot window and warning when history is truncated. The product should therefore no longer describe the returned tail as if it were silently known to cover the selected range.
The core aggregation defect remains: GET /api/usage still reads the bounded management snapshot first and applies 7d, 30d, or all filtering afterward. On a high-volume installation, the loaded tail can cover much less than the requested period.
The issue stays open until date-range and all-time aggregates are complete across the retained ledger rather than merely truthful about truncation.
Problem
managementUsageMaxReadBytes is 64 MiB by default. If usage.jsonl is larger than that, the management reader loads only the newest tail.
The range filter is applied after that read. As a result:
30d can omit persisted requests that are less than 30 days old;
Available history / all can return essentially the same bounded tail;
cumulative totals can decrease as older rows fall out of the moving read window;
detail rows may be bounded intentionally, but aggregate totals become incomplete too.
PR #1532 improves disclosure only. It does not change that aggregation boundary.
Original measured example
On OpenCodex 2.11.0 with a ledger larger than 64 MiB:
Source
Requests
Tokens
Time covered
Complete usage.jsonl
175,818
23.74B
Aug 4-11
Bounded Dashboard/API snapshot
46,417
6.60B
roughly 39 hours
The API reported truncation, and 129,401 requests plus 17.14B tokens inside the nominal 30-day range were not included in the aggregate.
Root cause
The management route performs the operations in this order:
Do not derive a rangeFullyCovered assertion only from the oldest loaded row timestamp.
usage.jsonl is appended when a request completes while a row can carry the request start time. Completion order and start-time order can differ, so the oldest timestamp in the loaded tail does not prove what timestamps may exist in the dropped prefix.
Preferred implementation direction
Use a rebuildable indexed or incremental aggregate projection for summaries, while keeping usage.jsonl as canonical evidence.
Possible implementations include:
the existing SQLite history index for range queries; or
Raising managementUsageMaxReadBytes is only a temporary mitigation.
Close condition
Close when 7d/30d aggregates cover all retained in-range requests and all-time totals remain monotonic across raw-tail rotation/truncation and restart.
Client or integration
OpenCodex Dashboard
Area
Dashboard / Usage
Current status
This issue is partially mitigated but not fixed.
PR #1532 landed on
devand made the bounded read visible to users by exposing the observed snapshot window and warning when history is truncated. The product should therefore no longer describe the returned tail as if it were silently known to cover the selected range.The core aggregation defect remains:
GET /api/usagestill reads the bounded management snapshot first and applies7d,30d, orallfiltering afterward. On a high-volume installation, the loaded tail can cover much less than the requested period.The issue stays open until date-range and all-time aggregates are complete across the retained ledger rather than merely truthful about truncation.
Problem
managementUsageMaxReadBytesis 64 MiB by default. Ifusage.jsonlis larger than that, the management reader loads only the newest tail.The range filter is applied after that read. As a result:
30dcan omit persisted requests that are less than 30 days old;Available history/allcan return essentially the same bounded tail;PR #1532 improves disclosure only. It does not change that aggregation boundary.
Original measured example
On OpenCodex 2.11.0 with a ledger larger than 64 MiB:
usage.jsonlThe API reported truncation, and 129,401 requests plus 17.14B tokens inside the nominal 30-day range were not included in the aggregate.
Root cause
The management route performs the operations in this order:
The desired contract requires the date/range aggregation boundary to precede, or be independent of, the bounded recent-detail read.
Required behavior
7daggregates every retained valid request in the selected 7-day range.30daggregates every retained valid request in the selected 30-day range.snapshotWindowStart/snapshotWindowEnddisclosure from fix(usage): disclose the window a truncated read actually covers #1532 remains truthful and must not be reinterpreted as a proof of complete range coverage.Important correctness constraint
Do not derive a
rangeFullyCoveredassertion only from the oldest loaded row timestamp.usage.jsonlis appended when a request completes while a row can carry the request start time. Completion order and start-time order can differ, so the oldest timestamp in the loaded tail does not prove what timestamps may exist in the dropped prefix.Preferred implementation direction
Use a rebuildable indexed or incremental aggregate projection for summaries, while keeping
usage.jsonlas canonical evidence.Possible implementations include:
Raising
managementUsageMaxReadBytesis only a temporary mitigation.Close condition
Close when 7d/30d aggregates cover all retained in-range requests and all-time totals remain monotonic across raw-tail rotation/truncation and restart.
Related