Rate limit
The
ratelimit custom resource definition (CRD) lets you configure rate limiting and throttling policies on NetScaler® using Kubernetes-native configuration. You can use the ratelimit CRD to protect your services and AI backends from overload by limiting the rate of requests, connections, or tokens.
You can use the
ratelimit CRD to:
-
Throttle traffic based on request rate, connection count, or token rate.
-
Apply limits per client IP address, per API path, per HTTP method, or per API client identified by an HTTP header.
-
Choose the action to take when a limit is exceeded, such as dropping, resetting, redirecting, or responding to requests.
-
Collect traffic analytics with stream identifiers for observability of requests, connections, response times, bandwidth, and token usage.
The
ratelimit CRD is referenced from an aigatewayroute or an mcproute through an ExtensionRef filter, or applied directly to services through servicenames or targetRef.
Note:
You must specify at least one of
ratelimits or streams.
Deploy the ratelimit CRD
The ratelimit CRD is in the ratelimit-crd.yaml file in the NetScaler Ingress Controller GitHub repository. The NetScaler Kubernetes Gateway Controller Helm chart also installs it. Deploy the CRD using the following command:
kubectl create -f https://raw.githubusercontent.com/netscaler/netscaler-k8s-ingress-controller/master/crd/ratelimit/ratelimit-crd.yaml
Note:
Do not modify the CRD deployment YAML file.
ratelimit CRD attributes
Note:
In NetScaler Kubernetes Gateway Controller 2.2.0 and later releases, attributes of
ratelimit CRD schema are updated to be under the ratelimits spec. Also, new rate limit attributes are introduced. In previous releases, ratelimit CRD schema was defined directly under spec.
The following table lists the top-level attributes available under
spec for the ratelimit CRD.
| Attribute | Description | Supported values |
|---|---|---|
ingressclass |
Ingress class. If not specified, all NetScaler Ingress Controllers in the cluster process the resource. Otherwise, only the controller with that ingress class processes it. | String |
servicenames |
Name of the services to which the rate limit policies are applied. | Array of strings (maximum length 127) |
gatewayClassName |
Name of the GatewayClass that this profile is applied to. |
String |
targetRef |
List of target resources where this profile is applied. | Array |
selector_keys |
Traffic match criteria to which the rate limit or throttling applies. | Object |
ratelimits |
List of rate limit configurations. | Array |
streams |
List of stream identifier configurations for traffic analytics and tracking. | Array |
goto_priority_expression |
Priority expression applied to the rate limit responder policy bindings created for this resource. NEXT continues policy evaluation after this policy. END stops it. Use END when throttle_action is a terminating action such as RESPOND. |
NEXT, END |
targetRef attributes
| Attribute | Description |
|---|---|
name |
Name of the target resource. |
namespace |
Namespace of the target resource. |
group |
Group of the target resource. |
kind |
Kind of the target resource. |
sectionName |
Specific section within the target resource. |
selector_keys attributes
The
selector_keys.basic object defines the traffic stream selection criteria. All keys are applied as an AND condition. If no keys are specified, the rate limit applies at the service level.
| Attribute | Description | Supported values |
|---|---|---|
path |
API resource path prefix match, for example /api/v1/products. |
Array of strings |
method |
HTTP methods to match. | GET, PUT, POST, DELETE, HEAD, OPTIONS, TRACE, CONNECT, PATCH, UNKNOWN_METHOD |
header_name |
HTTP header that identifies the unique API client, for example X-apikey. |
String |
per_client_ip |
When set, applies the throttling limit to each unique client IP address accessing the API resource. | Boolean |
The
selector_keys.advanced object keys the rate limit counter on arbitrary NetScaler stream-selector expressions instead of the fixed basic keys. For example, you can use a field from a JSON-RPC request body to set a rate limit for each MCP tool. The advanced selector is mutually exclusive with basic.
| Attribute | Description | Supported values |
|---|---|---|
rules |
NetScaler stream-selector expressions. NetScaler Kubernetes Gateway Controller adds each item as a separate expression to the stream selector that it creates on NetScaler. For example, HTTP.REQ.BODY(100000).XPATH_JSON(xp%/params/name%) reads the name field inside the params object of a JSON request body. |
Array of 1-5 strings (maximum length 7991 each) |
include_base_selectors |
When true (default), HTTP.REQ.LB_VSERVER.NAME and HTTP.REQ.HOSTNAME are appended to the selector. Set to false to use only rules, for example for a global per-tool limit. |
Boolean |
match |
Optional NetScaler Boolean expression that is added to the rule of the rate limit responder policy with a logical AND (&&), so the limit applies only to matching traffic. For example, http.req.body(100000).xpath_json(xp%/method%).eq("tools/call") matches only requests whose JSON body has method set to tools/call. |
String (maximum length 7991) |
ratelimits attributes
Each entry in
ratelimits supports the following attributes. The req_threshold attribute is required.
| Attribute | Description | Supported values |
|---|---|---|
req_threshold |
Maximum requests per timeslice to be allowed. This field is required. | Integer |
timeslice |
Timeslice in milliseconds, in multiples of 10. Defaults to 1000 milliseconds. | Integer |
limittype |
Limit type. Defaults to BURSTY if not specified. With mode: TOKEN_RATE, only BURSTY is supported. |
BURSTY, SMOOTH |
mode |
Metric to which the limit is applied. Defaults to REQUEST_RATE if not specified. |
REQUEST_RATE, CONNECTION, TOKEN_RATE |
alertsintimeslice |
Number of alerts to raise within a timeslice. | Integer |
throttle_action |
Action to take when the limit is exceeded. Defaults to RESPOND. DROP drops requests exceeding the limit, RESET resets the client connection, REDIRECT redirects to the specified URL, RESPOND responds with HTTP/1.1 429 Too Many Requests and a Retry-After header, or with respond_with when it is set. |
DROP, RESET, REDIRECT, RESPOND, NOOP |
redirect_url |
Redirect URL used when throttle_action is REDIRECT. |
String |
respond_with |
Custom NetScaler respondwith target expression used when throttle_action is RESPOND. Overrides the default HTTP 429 response, for example an MCP JSON-RPC error body that echoes the request jsonrpc and id fields. |
String (maximum length 7991) |
logpackets |
Adds an audit message action that specifies whether to log the message, and to which log. | Object (logexpression, loglevel) |
The
logpackets object supports the following attributes. Both are required when logpackets is used.
| Attribute | Description | Supported values |
|---|---|---|
logexpression |
Default-syntax expression that defines the format and content of the log message. | String (maximum length 7991) |
loglevel |
Audit log level that specifies the severity of the generated log message. | EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFORMATIONAL, DEBUG |
streams attributes
Each entry in
streams supports the following attributes. The sort attribute is required.
| Attribute | Description | Supported values |
|---|---|---|
interval |
Number of minutes of data to use when calculating session statistics (number of requests, bandwidth, and response times). | Integer (1–10080) |
sampleCount |
Size of the sample from which to select a request for evaluation. To evaluate all requests, set the sample count to 1. | Integer (1–65535) |
sort |
Sort stored records by the specified statistics column, in descending order. This field is required. | REQUESTS (default), CONNECTIONS, RESPTIME, BANDWIDTH, RESPTIME_BREACHES, TOKENS, NONE |
snmpTrap |
Enable or disable SNMP trap for the stream identifier. | ENABLED, DISABLED |
appflowLog |
Enable or disable AppFlow logging for the stream identifier. | ENABLED, DISABLED |
trackAckOnlyPackets |
Track ACK-only packets. Applicable only when packet rate limiting is used. | ENABLED, DISABLED |
trackTransactions |
Track transactions exceeding the configured threshold. When set to TOKENS, the transaction threshold attributes do not apply. |
RESPTIME, TOKENS, NONE |
maxTransactionThreshold |
Maximum per-transaction value of the tracked metric. | Integer (minimum 0) |
minTransactionThreshold |
Minimum per-transaction value of the tracked metric. | Integer (minimum 0) |
acceptanceThreshold |
Non-breaching transactions to total transactions threshold, expressed as a percentage. A maximum of 6 decimal places is supported. | String (maximum length 10) |
breachThreshold |
Breaching transactions threshold calculated over the interval. | Integer (minimum 0) |
log |
Location where objects collected on the identifier are logged. | SYSLOG, NONE |
logInterval |
Time interval in minutes for logging the collected objects. Must be greater than or equal to the interval of the stream identifier. | Integer (1–10080) |
logLimit |
Maximum number of objects to be logged in the log interval. | Integer (1–1000) |
How to write the rate limit configuration
In the
ratelimit YAML definition, set the kind as ratelimit. In the spec section, select the traffic to throttle with selector_keys, and define the limits under ratelimits, the analytics under streams, or both.
Keep the following guidelines in mind:
-
Specify at least one of
ratelimitsorstreams. -
Use
mode: TOKEN_RATEto enforce token-based rate limiting for AI backends. -
Use
selector_keys.basic.per_client_iporheader_nameto apply per-client limits. -
Attach the
ratelimitCRD to anaigatewayrouteor anmcproutethrough anExtensionReffilter, or bind it to services throughservicenamesortargetRef.
Sample rate limit configurations
Token-based rate limiting
The following configuration limits traffic per client IP address to 100,000 tokens per minute and responds with a
429 status when the limit is exceeded.
apiVersion: citrix.com/v1beta1
kind: ratelimit
metadata:
name: token-ratelimit
namespace: default
spec:
selector_keys:
basic:
path:
- /v1/chat/completions
method:
- POST
per_client_ip: true
ratelimits:
- req_threshold: 100000
timeslice: 60000
mode: TOKEN_RATE
limittype: BURSTY
throttle_action: RESPOND
Per-API-client request rate limiting with logging
The following configuration limits each API client (identified by the
X-apikey header) to 500 requests per second and logs when the limit is breached.
apiVersion: citrix.com/v1beta1
kind: ratelimit
metadata:
name: apikey-ratelimit
namespace: default
spec:
servicenames:
- ai-backend-service
selector_keys:
basic:
header_name: X-apikey
ratelimits:
- req_threshold: 500
timeslice: 1000
mode: REQUEST_RATE
limittype: BURSTY
throttle_action: DROP
logpackets:
logexpression: "\"Rate limit exceeded for client: \" + HTTP.REQ.HEADER(\"X-apikey\")"
loglevel: WARNING
Stream identifier for traffic analytics
The following configuration collects analytics on token usage without enforcing a limit.
apiVersion: citrix.com/v1beta1
kind: ratelimit
metadata:
name: token-analytics
namespace: default
spec:
selector_keys:
basic:
path:
- /v1/chat/completions
streams:
- interval: 5
sampleCount: 1
sort: TOKENS
appflowLog: ENABLED
trackTransactions: TOKENS
log: SYSLOG
logInterval: 5
logLimit: 100