Rate limit dimensions
Dimension keys determine how the gateway groups traffic into rate limit buckets. Each dimension key references a value from the request context. The gateway resolves these values at runtime to find the matching rate limit entry.
Supported dimensions
| Dimension key | Description | Example value |
|---|---|---|
|
|
The name of the target being invoked. Resolved from the request path. |
|
|
|
The fully-qualified name of the tool being invoked, in the format |
|
|
|
The fully qualified model identifier for inference targets. |
|
|
|
A claim extracted from the caller’s JWT token. Replace |
|
|
|
The IAM principal ARN of the caller. |
|
|
|
The source identity set by the caller when assuming a role. |
|
|
|
The value of a caller-supplied request header. Replace |
|
|
|
The value of a field in the JSON request body, addressed by a simple dotted path. Replace |
|
Custom request header and body dimensions
The $.context.request.header.<name> dimension groups traffic by a caller-supplied request header. The $.context.request.body.<path> dimension groups traffic by a field in the JSON request body. For example, you can rate limit by a tenant tier passed in an X-Customer-Id header, or by a workload_type field in the request body.
Required identity co-dimension
Because the caller supplies the header or body value, a custom request header or body dimension cannot be used on its own. Each rate limit that uses one of these dimensions must also include a trusted identity co-dimension in the same rate limit, so that each bucket is scoped to an authenticated identity:
-
For a gateway with IAM (SigV4) inbound authentication, include an
$.context.iam.*dimension (for example,$.context.iam.principal). -
For a gateway with OAuth (JWT) inbound authentication, include a
$.context.jwt.<claim>dimension (for example,$.context.jwt.sub).
The gateway rejects a rate limit that specifies a custom request header or body dimension without a matching identity co-dimension, returning a ValidationException at creation. A gateway’s inbound authentication must be bindable to an IAM or JWT identity to use these dimensions. For example, a gateway configured with no inbound authentication cannot use custom request header or body dimensions.
Note
The identity co-dimension can appear in any position in dimensionKeys relative to the header or body dimension; it only has to be present in the same rate limit.
Selector syntax and value constraints
Custom request header and body selectors use a fixed field-pointer grammar — JSONPath operators (such as filters, wildcards, or array slices) are not supported:
-
A header selector is
$.context.request.header.<name>, where<name>is a single HTTP header name. -
A body selector is
$.context.request.body.<path>, where<path>is a dotted path of object field names (for example,metadata.customer.tier). Each segment addresses a nested JSON object field; the final segment must resolve to a scalar (string, number, or boolean) value. -
A selector can be at most 128 characters.
At runtime, the gateway resolves the value and applies the following rules before using it as a bucket key:
-
Leading and trailing whitespace is removed. Values are case-sensitive and are otherwise used exactly as supplied (for example,
goldandGoldare distinct values). -
A resolved value can be at most 256 characters and must not contain
/,|,,, the*character, or control characters. A value that violates these rules causes the dimension to be skipped for that request (see Dimension resolution behavior).
The default value (*)
Rate limit entries support the special value * as a catch-all default for a dimension.
-
An entry with
*for a dimension means "apply this rate to all values of this dimension." -
If a more specific entry exists for the actual value, the specific entry takes precedence (most-specific match wins).
-
*creates independent per-entity buckets — each distinct value that matches gets its own rate bucket at the configured rate.
Trailing-only constraint for multi-dimension rate limits:
When a rate limit has multiple dimension keys,
can only appear in trailing positions. If you use at position N, all subsequent positions must also be *.
For example, with dimensionKeys: ["targetName", "toolName", "$.context.jwt.sub"]:
| Entry dimensions | Valid | Why |
|---|---|---|
|
|
Yes |
All positions are specific values. |
|
|
Yes |
Only the last position is |
|
|
Yes |
Trailing positions are |
|
|
Yes |
All positions are |
|
|
No |
|
|
|
No |
|
|
|
No |
|
How matching works:
When a request arrives, the gateway resolves the actual dimension values and looks for the most specific matching entry. For example, if the resolved values are ["target1", "readData", "alice"], the gateway checks entries in this order:
-
["target1", "readData", "alice"]— exact match (most specific) -
["target1", "readData", "*"]— last dimension uses default -
["target1", "*", "*"]— last two dimensions use default -
["*", "*", "*"]— fully default (least specific)
The first match wins.
Tip
Use specific entries for known high-value or restricted entities, and * entries as default rate tiers for everything else.
Dimension resolution behavior
When the gateway evaluates a rate limit, it resolves each dimension key from the request context:
-
If a dimension key cannot be resolved from the request (for example,
toolNameon a non-tool request, or a JWT claim that does not exist), the gateway skips that rate limit entirely. The request is not throttled by that rate limit. -
A custom request header or body dimension is skipped the same way when the value cannot be resolved to a usable value. This happens when the header is absent, the request body is not valid JSON, the dotted path does not exist or does not resolve to a scalar, or the resolved value violates the value constraints (see Selector syntax and value constraints).
-
Only validated context is used for resolution. JWT claims are extracted from tokens that have been validated by the gateway’s authentication configuration. IAM context is available only for SigV4-authenticated requests.
Shared vs individual limits
The combination of dimension keys and entry values determines whether traffic shares a single rate bucket or each entity gets its own independent bucket.
| dimensionKeys | Entry dimensions | Behavior |
|---|---|---|
|
|
|
All traffic to |
|
|
|
Each target gets its own independent bucket at this rate (per-entity). |
|
|
|
Each unique caller gets their own bucket (individual per-caller limit). |
|
|
|
Each caller gets their own bucket, scoped to |
|
|
|
Each unique target-and-caller combination gets its own bucket. |
Warning
Avoid using high-cardinality or unbounded dimension values as dimension keys — for example JWT claims such as $.context.jwt.jti or $.context.jwt.nonce, or custom request header/body selectors that carry per-request-unique values such as a request ID, trace ID, or UUID (for example, $.context.request.header.X-Request-Id). These create an unbounded number of rate buckets, which might reduce the effectiveness of rate limiting. Use stable, bounded identifiers such as sub, team, or tier instead.