kgateway version
2.3.2
Is your feature request related to a problem? Please describe.
I want global rate limiting but don't want every incoming request to result in a call to the rate limiting service which will add latency to each request. I want asynchronous rate limiting (sometimes called async-evaluate or post-evaluate) where the proxy lets the request through while simultaneously asking the rate limit service for a decision. If the limit is hit, only the next request is blocked.
I read this is how companies like Cloudflare implement their rate limiting system.
This is why the increment jobs are run asynchronously without slowing down the requests. If the request rate is above the threshold, another piece of data is stored asking all servers in the PoP to start applying the mitigation for that client. Only this bit of information is checked during request processing.
Kgateway's global rate limiting doc suggests the only mode is synchronous.
- The Gateway extracts descriptors and sends them to the Rate Limit Service.
- The Rate Limit Service applies configured limits for those descriptors and returns a decision to the Gateway.
- If allowed, the Gateway forwards the request to the App.
- If the rate limit is reached, the Gateway denies the request and returns a message to the Client.
Describe the solution you'd like
Envoy's global HTTP rate-limit filter supports apply_on_stream_done on route/vhost-level
RateLimit actions (envoy.config.route.v3.RateLimit.apply_on_stream_done), which sends the
rate-limit-service call after the stream completes instead of gating the request:
A rate limit applied on the stream completion is "fire-and-forget" by nature, and rate limit
is not enforced by this config. In other words, the current request won't be blocked when this
is true, but the budget will be updated for the subsequent requests based on the action with
this field set to true.
This removes the RLS round trip from the request's critical path — the current request proceeds
immediately, and only a later request can be denied once the budget is exceeded.
kgateway's TrafficPolicy.spec.rateLimit.global (RateLimitPolicy in
api/v1alpha1/kgateway/traffic_policy_types.go) currently only exposes descriptors and
extensionRef, with no way to set this field. Requesting it be surfaced on
RateLimitDescriptor/RateLimitPolicy so users can trade strict enforcement for latency
(e.g. combining a synchronous descriptor for a hard ceiling with an apply_on_stream_done
descriptor for cost/usage-based accounting).
Describe alternatives you've considered
No response
Additional Context
Related: this is distinct from #6540 (shadow mode), which never enforces at all rather than
deferring enforcement to a subsequent request.
kgateway version
2.3.2
Is your feature request related to a problem? Please describe.
I want global rate limiting but don't want every incoming request to result in a call to the rate limiting service which will add latency to each request. I want asynchronous rate limiting (sometimes called async-evaluate or post-evaluate) where the proxy lets the request through while simultaneously asking the rate limit service for a decision. If the limit is hit, only the next request is blocked.
I read this is how companies like Cloudflare implement their rate limiting system.
Kgateway's global rate limiting doc suggests the only mode is synchronous.
Describe the solution you'd like
Envoy's global HTTP rate-limit filter supports
apply_on_stream_doneon route/vhost-levelRateLimitactions (envoy.config.route.v3.RateLimit.apply_on_stream_done), which sends therate-limit-service call after the stream completes instead of gating the request:
This removes the RLS round trip from the request's critical path — the current request proceeds
immediately, and only a later request can be denied once the budget is exceeded.
kgateway's
TrafficPolicy.spec.rateLimit.global(RateLimitPolicyinapi/v1alpha1/kgateway/traffic_policy_types.go) currently only exposesdescriptorsandextensionRef, with no way to set this field. Requesting it be surfaced onRateLimitDescriptor/RateLimitPolicyso users can trade strict enforcement for latency(e.g. combining a synchronous descriptor for a hard ceiling with an
apply_on_stream_donedescriptor for cost/usage-based accounting).
Describe alternatives you've considered
No response
Additional Context
Related: this is distinct from #6540 (shadow mode), which never enforces at all rather than
deferring enforcement to a subsequent request.