Skip to content

Usage control

Usage control limits how many requests a caller can make in a period of time. A caller that goes over a limit gets 429 Too many requests.

Usage control rules are defined under Rules.UsageControlRules and bound by name with UsageControlRules on GlobalConfig, a server or a route. Each scope accepts a list, so several rules can be bound at once, for example one rule for bursts and another for a longer period.

Rules:
UsageControlRules:
per-minute:
RequestCount: 60
WindowTime: 1m
per-hour:
RequestCount: 1000
WindowTime: 1h
ServerConfigs:
svc-a:
URL: "http://svc-a:9090"
UsageControlRules: [per-minute, per-hour]
Key Required Description
RequestCount yes Number of requests allowed in the window. Must be greater than zero.
WindowTime yes Length of the window: a positive whole number followed by a unit.

Units for WindowTime:

Unit Meaning Example
m minutes 1m, 30m
h hours 1h, 5h
w weeks 1w
Mo months (30 days) 1Mo

The count is kept per caller, see client ID rules for how callers are identified. A rule with RequestCount: 20 and WindowTime: 1m allows each caller 20 requests per minute.

A request is checked against the rules bound to GlobalConfig, to the server of the route and to the route itself. The request is rejected as soon as one rule is exceeded. Within a scope, rules with the shortest window are checked first.

UsageControlMode on a server or a route chooses which scopes are checked.

Mode Behavior
Cascade (default) Global, server and route rules all apply. The request must pass every one.
Strict The scope stops the cascade, rules of the scopes above it are ignored.

With Strict:

Set on Rules checked
a route only the route’s rules, server and global rules are ignored
a server the global rules are ignored
GlobalConfig:
UsageControlRules: [global-limit]
ServerConfigs:
svc-a:
URL: "http://svc-a:9090"
UsageControlRules: [server-limit]
ServerRoutes:
checkout-status:
TargetServer: svc-a
PathPattern: /api/status/checkout
UsageControlMode: Strict # only this route's rules apply here
UsageControlRules: [strict-2-per-min]
checkout:
TargetServer: svc-a
PathPattern: /api/checkout # Cascade: global-limit + server-limit

A rejected request gets status 429 with the body Too many requests. It appears in the access log with response_status 429, and counts in gw_requests_total with reason="rate_limited" when Prometheus is enabled.

  • RequestCount of zero or less is an error.
  • A WindowTime that is not a positive whole number followed by m, h, w or Mo is an error.
  • Binding a usage control rule that does not exist is an error.
  • Having no usage control rules at all is a warning: callers are not limited.