Context
A profiling audit of the zero-config hot path found the request lifecycle loads the config snapshot handle up to 6 times per chat request (auth extractor, dispatch, quota gate, request-metrics emit x2, usage-event emit; +1 on the streaming path) and resolves the same ProviderKey 4-5 times (dispatch-time resolutions plus provider_key_metric_name twice in request_metrics::record/record_usage and the telemetry-tags lookup in emit_usage_event).
The dominant costs found by the same audit (full exporter-table scans per request, empty-table shard walks) have been fixed at the ResourceTable chokepoint. What remains is the structural part:
- Thread one
Arc<AisixSnapshot> (loaded once at dispatch entry) through the emit helpers (emit_usage_event, request_metrics::record/record_usage) instead of re-loading per helper. Note this freezes a request's config view to its start, which is arguably more correct but is a small observable change for exporters added mid-request.
- Resolve the attempt's ProviderKey entry once per completion and pass the resolved entry (or its display name + telemetry tags) into the metric and usage emitters instead of re-resolving by id in each.
Why deferred
Each load is one atomic RMW and each resolution one DashMap read + small clone (~0.5us/request combined, frame-inclusive). Capturing it means changing the signatures of emit helpers shared by the whole endpoint family (10+ handler files, streaming and non-streaming branches) — a wide, cross-family diff that was out of proportion for the remaining size in the zero-config package PR. Doing it later as a focused refactor keeps the family in lockstep in one review.
Size
~0.4-0.6us/request estimated recoverable; touches aisix-proxy handler family + request_metrics + usage_attr.
Context
A profiling audit of the zero-config hot path found the request lifecycle loads the config snapshot handle up to 6 times per chat request (auth extractor, dispatch, quota gate, request-metrics emit x2, usage-event emit; +1 on the streaming path) and resolves the same ProviderKey 4-5 times (dispatch-time resolutions plus
provider_key_metric_nametwice inrequest_metrics::record/record_usageand the telemetry-tags lookup inemit_usage_event).The dominant costs found by the same audit (full exporter-table scans per request, empty-table shard walks) have been fixed at the
ResourceTablechokepoint. What remains is the structural part:Arc<AisixSnapshot>(loaded once at dispatch entry) through the emit helpers (emit_usage_event,request_metrics::record/record_usage) instead of re-loading per helper. Note this freezes a request's config view to its start, which is arguably more correct but is a small observable change for exporters added mid-request.Why deferred
Each load is one atomic RMW and each resolution one DashMap read + small clone (~0.5us/request combined, frame-inclusive). Capturing it means changing the signatures of emit helpers shared by the whole endpoint family (10+ handler files, streaming and non-streaming branches) — a wide, cross-family diff that was out of proportion for the remaining size in the zero-config package PR. Doing it later as a focused refactor keeps the family in lockstep in one review.
Size
~0.4-0.6us/request estimated recoverable; touches aisix-proxy handler family + request_metrics + usage_attr.