Context
On deployments where budget enforcement is disabled (BudgetClient::disabled(), i.e. standalone mode with no cp-api), every request still pays a constant gauge write: chat.rs calls record_budget_gauges(..., None) -> clear_budget_gauges -> aisix_budget_details_present{api_key_id,team_id,user_id} = 0. The write costs ~0.2us/request (label-key construction dominates; the cached-handle path still builds the 3-label key every time).
Why it was not included in the zero-config fast-path package
Gating the write on "budgets disabled" removes the aisix_budget_details_present series for keys that have traffic, which violates the /metrics series-compatibility invariant the package is shipped under. The alternatives all have worse trade-offs:
- Value-memoisation only saves the atomic store, not the label-key construction (the dominant cost).
- A periodic resync over
snapshot.apikeys would inflate the series set from "keys with traffic" to "all configured keys" — unacceptable on deployments with very large key counts.
What this issue asks for
Decide and implement one of:
- Accept the series change: when budgets are disabled, do not emit
aisix_budget_details_present at all (documented behavior change, changelog entry). The gauge is arguably meaningless when no budget subsystem is active.
- Emit the 0-value series once per key (first request) instead of every request, preserving series presence with a bounded write cost.
- Keep the status quo and close as won't-fix with rationale.
Option 2 preserves the observable contract exactly (a gauge is level-triggered; re-writing 0 every request is redundant) and is likely the cheapest safe form.
Size
~0.2us/request on the zero-config hot path (~4% of the package's total recoverable time). Low priority, pure telemetry-cost hygiene.
Context
On deployments where budget enforcement is disabled (
BudgetClient::disabled(), i.e. standalone mode with no cp-api), every request still pays a constant gauge write:chat.rscallsrecord_budget_gauges(..., None)->clear_budget_gauges->aisix_budget_details_present{api_key_id,team_id,user_id} = 0. The write costs ~0.2us/request (label-key construction dominates; the cached-handle path still builds the 3-label key every time).Why it was not included in the zero-config fast-path package
Gating the write on "budgets disabled" removes the
aisix_budget_details_presentseries for keys that have traffic, which violates the /metrics series-compatibility invariant the package is shipped under. The alternatives all have worse trade-offs:snapshot.apikeyswould inflate the series set from "keys with traffic" to "all configured keys" — unacceptable on deployments with very large key counts.What this issue asks for
Decide and implement one of:
aisix_budget_details_presentat all (documented behavior change, changelog entry). The gauge is arguably meaningless when no budget subsystem is active.Option 2 preserves the observable contract exactly (a gauge is level-triggered; re-writing 0 every request is redundant) and is likely the cheapest safe form.
Size
~0.2us/request on the zero-config hot path (~4% of the package's total recoverable time). Low priority, pure telemetry-cost hygiene.