When multiple ingress gateway replicas handle traffic independently, a single replica cannot enforce cluster-wide rate limits. Global throttling solves this by routing all rate-limit decisions through a centralized gRPC service backed by Redis, so request counts are shared across all replicas. Use it to protect backend services from traffic bursts, overload, and abuse.
This topic walks through five throttling scenarios -- from broad route-level limits to fine-grained per-client-IP controls. All scenarios share the same base setup: a throttling service, a sample application, and the ASMGlobalRateLimiter custom resource.
How global throttling works
Global throttling relies on a dedicated gRPC-based throttling service (built on Envoy's rate limit service) and a Redis backend to track request counts across all gateway replicas.
Create an
ASMGlobalRateLimiterresource in the ASM control plane to define the throttling rule.ASM reconciles the resource and generates the throttling service configuration in the resource's
status.config.yamlfield.Copy the generated configuration into the
ratelimit-configConfigMap in the data plane cluster.On each inbound request, the ingress gateway queries the throttling service. When the limit is exceeded, the gateway returns
429 Too Many Requests.
The manual ConfigMap update is required because the throttling service runs in the data plane cluster, while the CRD is managed in the ASM control plane. Update the ConfigMap after every rule change to keep the two in sync.
Choose the right scenario
| Scenario | Throttle by | Use case | ASM version |
|---|---|---|---|
| 1. Route-level throttling | Specific route | Limit all traffic on a single route | 1.18.0.131+ |
| 2. Domain and port throttling | Domain + port | Limit all traffic to a host:port combination | 1.18.0.131+ |
| 3. Header and query parameter throttling | Request headers and query parameters | Limit only requests matching specific headers or query strings | 1.19.0+ |
| 4. Client IP throttling | Specific client IP or CIDR block | Block or limit a known abusive IP | 1.19.0+ |
| 5. Per-client-IP throttling | Each client IP independently | Enforce per-IP quotas across all clients | 1.25.0+ |
Prerequisites
A managed Kubernetes cluster added to your ASM instance, running ASM version 1.18.0.131 or later. See Add a cluster to an ASM instance.
Automatic sidecar injection enabled for the
defaultnamespace. See Enable automatic injection.An ingress gateway named
ingressgatewaywith port 80 enabled. See Create an ingress gateway.
Preparations
Before configuring throttling rules, deploy the throttling service and a sample application.
Deploy the throttling service
The throttling service has two components: a Redis instance that stores rate counters, and the Envoy rate limit service that evaluates requests against configured limits.
Create a file named
ratelimit-svc.yaml.Connect to your ACK cluster with kubectl and deploy the throttling service. For details, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.
kubectl apply -f ratelimit-svc.yaml
Deploy the Bookinfo sample application
Download the
bookinfo.yamlfile from the Istio repository on GitHub.Deploy the Bookinfo application in the ACK cluster.
kubectl apply -f bookinfo.yamlCreate a file named
bookinfo-gateway.yaml.Connect to the ASM instance with kubectl and create the Gateway and VirtualService. For details, see Use kubectl on the control plane to access Istio resources. This creates a route named
productpage-route-name1for thebf2.example.comdomain. It matches requests to/productpage,/static,/login,/logout, and/api/v1/products, and forwards them to theproductpageservice on port 9080.kubectl apply -f bookinfo-gateway.yaml
Common procedure for applying throttling rules
Every scenario in this topic follows the same three-step process after creating the ASMGlobalRateLimiter YAML:
Apply the rule in the ASM control plane:
kubectl apply -f global-ratelimit-gw.yamlExtract the generated configuration from the reconciled resource: Locate the
status.config.yamlfield in the output and copy its content exactly.kubectl get asmglobalratelimiter global-test -n istio-system -o yamlUpdate the ConfigMap in the ACK cluster. Paste the
config.yamlcontent into thedata.config.yamlfield of theratelimit-configConfigMap, then apply: The ConfigMap format:kubectl apply -f ratelimit-config.yamlapiVersion: v1 kind: ConfigMap metadata: name: ratelimit-config data: config.yaml: | # Paste the content from status.config.yaml here
Scenario 1: Route-level throttling
Limit all traffic on a specific virtual service route. This example limits the productpage-route-name1 route at bf2.example.com:80 to 1 request per minute.
Step 1: Create the throttling rule
Create a file named global-ratelimit-gw.yaml:
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMGlobalRateLimiter
metadata:
name: global-test
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
rateLimitService:
host: ratelimit.default.svc.cluster.local
port: 8081
timeout:
seconds: 5
isGateway: true
configs:
- name: productpage
limit:
unit: MINUTE
quota: 1
match:
vhost:
name: bf2.example.com
port: 80
route:
name_match: productpage-route-name1Key fields:
| Field | Description |
|---|---|
workloadSelector | Targets the ingress gateway workload. Set to istio: ingressgateway. |
isGateway | Must be true for gateway-level throttling. |
rateLimitService | Address and timeout for the throttling service deployed in the Preparations section. |
limit.unit / limit.quota | Time window and request count. MINUTE with quota: 1 allows 1 request per minute. |
vhost | Matches the domain, port, and route. name and port must match the VirtualService host and gateway port. route.name_match must match the route name in the VirtualService. |
For a complete field reference, see ASMGlobalRateLimiter CRD description.
Step 2: Apply and sync the configuration
Follow the common procedure to apply the rule, extract the generated configuration, and update the ConfigMap.
Step 3: Verify
Send two requests to the ingress gateway within one minute. Replace <ASM-gateway-IP> with your ingress gateway IP address. For details, see Obtain the ingress gateway address.
curl -H 'host: bf2.example.com' http://<ASM-gateway-IP>/productpage -v
curl -H 'host: bf2.example.com' http://<ASM-gateway-IP>/productpage -vThe first request succeeds. The second request returns a 429 response:
< HTTP/1.1 429 Too Many Requests
< x-envoy-ratelimited: true
< x-ratelimit-limit: 1, 1;w=60
< x-ratelimit-remaining: 0
< x-ratelimit-reset: 48Response headers:
| Header | Meaning |
|---|---|
x-envoy-ratelimited | Indicates the request was throttled. |
x-ratelimit-limit | The configured limit and window (1 request per 60-second window). |
x-ratelimit-remaining | Remaining requests in the current window. |
x-ratelimit-reset | Seconds until the rate limit window resets. |
Scenario 2: Domain and port throttling
Limit all traffic to a specific domain and port combination, regardless of route. This example limits all requests to bf2.example.com:80 to 1 request per minute.
Step 1: Create the throttling rule
Create a file named global-ratelimit-gw.yaml:
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMGlobalRateLimiter
metadata:
name: global-test
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
rateLimitService:
host: ratelimit.default.svc.cluster.local
port: 8081
timeout:
seconds: 5
isGateway: true
configs:
- name: productpage
limit:
unit: MINUTE
quota: 1
match:
vhost:
name: bf2.example.com
port: 80The only difference from Scenario 1 is that vhost does not include a route.name_match field, so the limit applies to all routes under the specified domain and port.
Step 2: Apply and sync the configuration
Follow the common procedure.
Step 3: Verify
Send two requests within one minute:
curl -H 'host: bf2.example.com' http://<ASM-gateway-IP>/productpage -v
curl -H 'host: bf2.example.com' http://<ASM-gateway-IP>/productpage -vThe first request succeeds. The second returns 429 Too Many Requests, confirming that domain-level throttling is active.
Scenario 3: Header and query parameter throttling
Requires ASM version 1.19.0 or later. See Update an ASM instance.
Throttle only requests that match specific headers and query parameters on a route. Other requests on the same route pass through unthrottled.
In this example, the productpage-route-name1 route allows 100,000 requests per second by default (effectively unlimited). Only requests containing both the ratelimit: "true" header and the ratelimit=enabled query parameter are limited to 1 request per minute.
Step 1: Create the throttling rule
Create a file named global-ratelimit-gw.yaml:
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMGlobalRateLimiter
metadata:
name: global-test
namespace: istio-system
spec:
workloadSelector:
labels:
app: istio-ingressgateway
rateLimitService:
host: ratelimit.default.svc.cluster.local
port: 8081
timeout:
seconds: 5
isGateway: true
configs:
- name: productpage
limit:
unit: SECOND
quota: 100000
match:
vhost:
name: bf2.example.com
port: 80
route:
name_match: productpage-route-name1
limit_overrides:
- request_match:
header_match:
- name: ratelimit
exact_match: "true"
query_match:
- name: ratelimit
exact_match: "enabled"
limit:
unit: MINUTE
quota: 1Key fields specific to this scenario:
| Field | Description |
|---|---|
limit (top-level) | Set to a high value (100,000/second) so normal traffic is not throttled. |
limit_overrides | Overrides the base limit for requests matching specific conditions. |
request_match.header_match | Matches requests with the ratelimit: "true" header (exact match). |
request_match.query_match | Matches requests with the ratelimit=enabled query parameter (exact match). |
limit_overrides.limit | The actual throttling limit for matched requests: 1 request per minute. |
Step 2: Apply and sync the configuration
Follow the common procedure.
Step 3: Verify
Test with matching headers and query parameters -- send two requests within one minute:
curl -H 'host: bf2.example.com' -H 'ratelimit: true' \
'http://<ASM-gateway-IP>/productpage?ratelimit=enabled' -v
curl -H 'host: bf2.example.com' -H 'ratelimit: true' \
'http://<ASM-gateway-IP>/productpage?ratelimit=enabled' -vThe first request succeeds. The second returns 429 Too Many Requests.
Test without matching headers -- send a request without the ratelimit header:
curl -H 'host: bf2.example.com' http://<ASM-gateway-IP>/productpage -vThis request succeeds, confirming that only requests matching the specified headers and query parameters are throttled.
Scenario 4: Client IP throttling
Requires ASM version 1.19.0 or later. See Update an ASM instance.
External Traffic Policy of the ingress gateway must be set to Local to preserve client IP addresses. See Create an ingress gateway.
Find the client IP in the downstream_remote_address field of the gateway access log.Throttle requests from a specific client IP address or CIDR block on a route. Other client IPs are unaffected.
Step 1: Create the throttling rule
Create a file named global-ratelimit-gw.yaml. Replace the IP address and subnet mask placeholders:
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMGlobalRateLimiter
metadata:
name: global-test
namespace: istio-system
spec:
workloadSelector:
labels:
app: istio-ingressgateway
rateLimitService:
host: ratelimit.default.svc.cluster.local
port: 8081
timeout:
seconds: 5
isGateway: true
configs:
- name: productpage
limit:
unit: SECOND
quota: 100000
match:
vhost:
name: bf2.example.com
port: 80
route:
name_match: productpage-route-name1
limit_overrides:
- request_match:
remote_address:
address: <client-IP> # Example: 106.11.XX.XX
v4_prefix_mask_len: <mask> # Example: 24 (for a /24 CIDR block)
limit:
unit: MINUTE
quota: 1Replace the following placeholders:
| Placeholder | Description | Example |
|---|---|---|
<client-IP> | The client IP address to throttle | 106.11.XX.XX |
<mask> | IPv4 subnet mask length (optional) | 24 |
Key fields specific to this scenario:
| Field | Description |
|---|---|
remote_address.address | The client IP address to match. |
remote_address.v4_prefix_mask_len | Optional. Specifies the subnet mask length to match a CIDR block instead of a single IP. |
Step 2: Apply and sync the configuration
Follow the common procedure.
Step 3: Verify
Test from the throttled IP -- send two requests within one minute:
curl -H 'host: bf2.example.com' http://<ASM-gateway-IP>/productpage -v
curl -H 'host: bf2.example.com' http://<ASM-gateway-IP>/productpage -vThe first request succeeds. The second returns 429 Too Many Requests.
Test from a different IP -- send a request from a client with a different IP address:
curl -H 'host: bf2.example.com' http://<ASM-gateway-IP>/productpage -vThis request succeeds, confirming that only the specified client IP is throttled.
Scenario 5: Per-client-IP throttling
Requires ASM version 1.25.0 or later. See Update an ASM instance.
External Traffic Policy of the ingress gateway must be set to Local. See Create an ingress gateway.
Find the client IP in the downstream_remote_address field of the gateway access log.Unlike Scenario 4 (which targets a specific IP), this scenario enforces independent rate limits for every client IP. Each IP gets its own quota.
Step 1: Create the throttling rule
Create a file named global-ratelimit-gw.yaml:
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMGlobalRateLimiter
metadata:
name: global-test
namespace: istio-system
spec:
workloadSelector:
labels:
app: istio-ingressgateway
rateLimitService:
host: ratelimit.default.svc.cluster.local
port: 8081
timeout:
seconds: 5
isGateway: true
configs:
- name: productpage
limit:
unit: SECOND
quota: 100000
target_services:
- name: bookinfo
namespace: default
kind: VirtualService
port: 80
section_name: productpage-route-name1
limit_overrides:
- request_match:
remote_address:
distinct: true
limit:
unit: MINUTE
quota: 1Key fields specific to this scenario:
| Field | Description |
|---|---|
remote_address.distinct | Set to true to maintain separate rate counters for each client IP. |
target_services | An alternative to vhost matching. Targets a specific VirtualService by name, namespace, kind, port, and section_name (route name). |
For a complete field reference, see ASMGlobalRateLimiter CRD description.
Step 2: Apply and sync the configuration
Apply the rule in the ASM control plane:
kubectl apply -f global-ratelimit-gw.yamlGet the reconciled status:
Update the ConfigMap with the generated configuration: Replace the
data.config.yamlfield with the content fromstatus.config.yaml:kubectl edit ConfigMap ratelimit-configapiVersion: v1 kind: ConfigMap metadata: name: ratelimit-config data: config.yaml: | descriptors: - descriptors: - key: remote_address rate_limit: requests_per_unit: 1 unit: MINUTE key: generic_key rate_limit: requests_per_unit: 100000 unit: SECOND value: RateLimit[global-test.istio-system]-Id[537612397] domain: ratelimit.default.svc.cluster.local
Step 3: Verify
Get the ingress gateway IP, then send two requests in a row:
export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -H 'host: bf2.example.com' http://$GATEWAY_URL:80/productpage -v
curl -H 'host: bf2.example.com' http://$GATEWAY_URL:80/productpage -vThe first request succeeds. The second returns 429 Too Many Requests, confirming that per-client-IP throttling is active. Each client IP has its own independent rate limit counter.
Related topics
Local throttling -- Enforce rate limits without a separate throttling service, using fewer resources. See Configure local throttling in Traffic Management Center.
Service-level global throttling -- Apply global throttling to inbound traffic for sidecar-injected services, not just the ingress gateway. See Use ASMGlobalRateLimiter to configure global throttling for ingress gateways and inbound traffic directed to services.