fix(billing): cache enterprise reporting-window usage sums for soft usage gates - #8267
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
There was a problem hiding this comment.
All reported issues were addressed across 8 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
|
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 5 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 11 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
…sage gates An enterprise usage period is a reporting window up to a year long, so every soft usage check re-summed the payer's whole year of usage_log, once per billable event (every run admission, Chat request, v1 API response, and knowledge document). For a busy enterprise org that scan ran thousands of times an hour and dominated database CPU. readSoftGateUsageCost serves reporting-window sums from a per-process LRUCache (fetchMethod, max 1000, 30 s TTL) keyed by payer, period source, and window bounds; concurrent misses coalesce and a failed sum is never cached. The raw cached reader is private and typed to reporting periods, so every other period is summed exactly. Pooled org admission (computePooledOrgUsage) and the v1 usage report (getEffectiveCurrentPeriodCost) read through it. The ledger only grows within a window, so a cached sum can only trail the true one by at most one TTL of usage: an admission gate may let a payer run on briefly past its limit, never refuse it wrongly. Exact paths are untouched: getBillingPeriodUsageCost itself (read-your-writes), threshold billing, cycle close, invoicing, analytics, and the execution logger's edge-triggered usage emails, which need an exact baseline.
07bcbfb to
08c9641
Compare
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Summary
usage_log— once per billable event (every run, Chat request, v1 API response, knowledge document). For a busy enterprise org that is a multi-second-per-call scan thousands of times an hour, and it dominates database CPUlib/billing/core/reporting-usage-cache.ts: oneLRUCache(fetchMethod,max1000, 30 s TTL) keyed by payer, period source, and window (not per actor); the cached reader is private and typed to reporting periods, reached only viareadSoftGateUsageCost; concurrent misses coalesce, a failed sum is never cachedcomputePooledOrgUsage→ Chat, wand, speech, uploads, credit/usage-gate routes, v1 limits, preprocessing misses) and v1getEffectiveCurrentPeriodCostgetBillingPeriodUsageCostitself (read-your-writes), threshold billing (exits for enterprise before summing), cycle close, invoicing, analytics, admin and displayType of Change
Testing
Cache coalescing, TTL expiry, key isolation (incl. by source), non-reporting bypass, failure-not-cached, executor bypass, admission routing (each revert-proven); lib/billing + lib/logs suites, type-check, lint, check:audits pass
Checklist