Skip to content

Follow up usage pagination SQL pushdown#166

Closed
zly2006 wants to merge 1 commit into
seakee:mainfrom
zly2006:codex/usage-sql-pagination-routes
Closed

Follow up usage pagination SQL pushdown#166
zly2006 wants to merge 1 commit into
seakee:mainfrom
zly2006:codex/usage-sql-pagination-routes

Conversation

@zly2006
Copy link
Copy Markdown

@zly2006 zly2006 commented Jun 5, 2026

This is a follow-up to #138.

#138 introduced the paged usage monitoring endpoints and documented that accounts/api-keys pagination was still a phase-one optimization. This PR implements the two follow-up items from that review:

  • push accounts/api-keys grouping, sorting, and LIMIT/OFFSET into SQL instead of building the full detail aggregate in Go memory first
  • replace usage endpoint suffix dispatch with exact path matching while preserving trailing slash normalization

Behavior note:

The SQL pushdown intentionally normalizes cached-token sorting at the event row level with sum(max(cached_tokens, cache_tokens)). The previous Go path grouped details first and then effectively summed max(sum(cached_tokens), sum(cache_tokens)) per detail group. The new row-level normalization is a small behavior difference for cachedTokens ordering when both fields are populated differently, but it matches the intended meaning of treating cached_tokens and cache_tokens as alternate sources for the same per-event cached-token metric.

Validation:

  • go test ./... from usage-service
  • npm run build

@zly2006 zly2006 force-pushed the codex/usage-sql-pagination-routes branch from 38abc2c to d58d36f Compare June 5, 2026 10:01
@zly2006
Copy link
Copy Markdown
Author

zly2006 commented Jun 7, 2026

Benchmark result on real off data: closing this PR.

I tested the branch on a snapshot of the live off Usage Service SQLite database, copied from /home/dom/services/cpa-manager/data/usage.sqlite. This was not mock data.

Dataset:

  • 39,037 usage_events
  • 9 model_prices
  • 5 iterations per scenario
  • page 1, page size 500

Average latency comparison:

Scenario In-memory avg SQLite avg Result
accounts / lastSeenAt 405 ms 555 ms SQLite is 1.37x slower
accounts / totalCalls 402 ms 556 ms SQLite is 1.38x slower
accounts / totalCost 397 ms 5630 ms SQLite is 14.18x slower
api-keys / lastSeenAt 401 ms 657 ms SQLite is 1.64x slower
api-keys / totalCalls 399 ms 655 ms SQLite is 1.64x slower
api-keys / totalCost 405 ms 5723 ms SQLite is 14.13x slower

Conclusion: on the current real production-sized dataset, this SQL pushdown does not improve performance. Normal sorts are slower by about 1.4-1.6x, and totalCost sorting is slower by about 14x, likely because the SQLite-side price matching/join CTE is too expensive for this query shape.

@zly2006
Copy link
Copy Markdown
Author

zly2006 commented Jun 7, 2026

Closing based on the real off-data benchmark above: this branch is slower than the in-memory path on the current dataset.

@zly2006 zly2006 closed this Jun 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant