44 type BillingAttributionSnapshot ,
55 checkAttributedUsageLimits ,
66} from '@/lib/billing/core/billing-attribution'
7+ import { USAGE_LEDGER_STATEMENT_TIMEOUT_MS } from '@/lib/billing/core/usage-log'
78import { coalesceLocally } from '@/lib/concurrency/singleflight'
89
910/**
@@ -21,17 +22,15 @@ import { coalesceLocally } from '@/lib/concurrency/singleflight'
2122export const USAGE_GATE_TTL_MS = 5 * 60 * 1000
2223
2324/**
24- * How long a coalesced ledger read may take before its callers give up on it. The read sums a
25- * payer's ledger for the billing period, which for a large organization is millions of rows and,
26- * from a cold cache or under heavy I/O, takes longer than the singleflight default of 30 s. That
27- * default exists to bound a hung producer, and a slow read is not a hung one: the database bounds
28- * every statement with its own timeout, after which the read fails on its own and the failure is
29- * reported rather than cached. The deadline therefore sits above any statement ceiling the
30- * deployment applies, so only a connection that never answers is given up on. A shorter deadline
31- * fails the callers while the read is still running, and the next caller starts a second read
32- * of the same ledger alongside it.
25+ * How long a coalesced usage read may take before its callers give up on it. The read's cost is
26+ * the ledger sum, which the database ends at {@link USAGE_LEDGER_STATEMENT_TIMEOUT_MS}; the
27+ * remainder is a few indexed lookups and the connection waits around them. The singleflight
28+ * default of 30 s exists to bound a hung producer, and a slow sum is not a hung one: given up on
29+ * early, it keeps running detached while every joined caller fails and the next caller starts a
30+ * second sum alongside it. Derived from the statement bound so the database always ends the sum
31+ * first, and the gate only gives up on a connection that never answers.
3332 */
34- export const USAGE_GATE_SETTLE_TIMEOUT_MS = 120_000
33+ export const USAGE_GATE_SETTLE_TIMEOUT_MS = USAGE_LEDGER_STATEMENT_TIMEOUT_MS + 15_000
3534
3635/**
3736 * Recent gate answers, admitted and refused, with `LRUCache` supplying the TTL
0 commit comments