Skip to main content

limit-req

Limits the request rate with a leaky bucket.

Category TrafficAdd it to Route, Service, Consumer, Consumer group, Global rule, Plugin configEngine plugin limit-reqPriority 1001

What it does​

limit-req holds the requests that reach a route to a steady rate. It counts them under a key that tells callers apart, for example the client address remote_addr. Requests per second is that rate, and Burst is how many requests may arrive above it before one is refused.

A request inside the burst waits until the rate allows it, unless No delay is on. A request above the burst is answered by the gateway itself with Rejected code, 503 unless you set another, as How G8 handles a request describes. With a rate of 10, a burst of 20 and the code set to 429 as in the example, 40 requests sent at once are answered partly 200 and partly 429.

When to use it​

  • A backend that copes with a steady flow but not with spikes: requests above the rate wait their turn instead of reaching it together.
  • A rate for each client address, for example 10 requests a second, where a client that sends a short burst is slowed down rather than refused.
  • A rate for each tenant rather than each address, with Key type set to var_combination and a key like $remote_addr-$http_x_tenant.
  • A rate that several gateway nodes enforce together, through one Redis server or a Redis cluster.

Not for a quota counted per time window, for example 100 requests a minute — see limit-count (Limits the number of requests in a time window, per key) or capping how many requests are open at once — see limit-conn (Limits concurrent connections per key).

Set it up​

Allow 10 requests a second for each client address and let 20 more wait their turn​

Under Basics set Requests per second to 10, set Burst to 20 and set Key to remote_addr. Under Behavior set Rejected code to 429.

limit-req · as the console saves it
{
"rate": 10,
"burst": 20,
"key": "remote_addr",
"rejected_code": 429
}

More scenarios​

Share the request rate across gateway nodes through one Redis server

Under Basics set Requests per second to 50, set Burst to 100 and set Key to remote_addr. Under Behavior set Policy to redis, set Redis host to redis.internal, leave Redis port at 6379 and set Redis password to <secret>.

limit-req · as the console saves it
{
"rate": 50,
"burst": 100,
"key": "remote_addr",
"policy": "redis",
"redis_host": "redis.internal",
"redis_port": 6379,
"redis_password": "<secret>"
}
Share the request rate across gateway nodes through a Redis cluster

Under Basics set Requests per second to 50, set Burst to 100 and set Key to remote_addr. Under Behavior set Policy to redis-cluster, set Redis cluster name to gateway-limits, fill Redis cluster nodes as in the JSON below and set Redis password to <secret>.

limit-req · as the console saves it
{
"rate": 50,
"burst": 100,
"key": "remote_addr",
"policy": "redis-cluster",
"redis_cluster_name": "gateway-limits",
"redis_cluster_nodes": [
"redis-1.internal:6379",
"redis-2.internal:6379",
"redis-3.internal:6379"
],
"redis_password": "<secret>"
}

Things to know​

  • Rejected code — Set to 429, the code that tells a client it sent too many requests: with a rate of 10 and a burst of 20, 40 requests sent at once are answered partly 200 and partly 429.
  • Rejected code — Unset, a request above the burst is answered 503, the answer of a service that is unavailable.
  • No delay — Off, a request inside the burst waits until the rate allows it, and on it is answered at once, with only requests above the burst refused.
  • Requests per second — Requests per second and Burst take a number. A $variable like $http_x_rate is refused when you save.
  • Requests per second — A rate of 0 is refused when you save.
  • Key — A variable the request does not carry, or a name with a dollar sign under Variable, is saved without a word, and every request is then counted by client address. So is a combination in which no $name resolves.
  • Policy — Policy is local, redis or redis-cluster. redis-sentinel is refused when you save.
  • Allow degradation — When the limit cannot be counted, because the store is unreachable or a value resolves to nothing, off answers 500 and on lets every request through unlimited.
  • AdviceBehind a load balancer, add real-ip to the same route, so that each client is held to the rate by its own address and not by the load balancer's.

Settings​

The fields as the console shows them, section by section. A field under “When … is …” is there only while that value is set.

Basics​

Requests per secondratenumberRequired

The steady number of requests per second let through, where a fraction such as 0.5 is allowed.

over 0
BurstburstnumberRequired

How many requests may arrive above the rate before one is refused.

at least 0
KeykeystringRequired

A request variable without its dollar sign, such as remote_addr, or text with $names under Variable combination.

example remote_addr
Key typekey_typestringdefault var

Variable reads one request variable by name, and Variable combination expands every $name in the text into one key.

one of var, var_combination

Behavior​

Policypolicystringdefault local
one of local, redis, redis-cluster

When Policy is redis​

Redis hostredis_hoststringRequired
at least 2 characters
Redis portredis_portintegerdefault 6379
at least 1
Redis databaseredis_databaseintegerdefault 0
at least 0
Redis usernameredis_usernamestring
at least 1 character
Redis passwordredis_passwordstring

Stored on the engine and shown only to roles that manage this object.

Redis SSLredis_sslbooleandefault false
Redis SSL verifyredis_ssl_verifybooleandefault false
Server name for TLSredis_server_namestring

The server name sent in the TLS handshake and, with verification on, checked against the certificate; unset, the host is sent, and an address never is.

at least 1 character
Redis timeoutredis_timeoutintegerdefault 1000
at least 1 · in milliseconds
Redis keepalive poolredis_keepalive_poolintegerdefault 100
at least 1
Redis keepalive timeoutredis_keepalive_timeoutintegerdefault 10000
at least 1000 · in milliseconds
When Policy is redis-cluster· 8 fields
Redis cluster nameredis_cluster_namestringRequired
Redis cluster nodesredis_cluster_nodesarray of stringsRequired
at least 1 item; each 2 to 100 characters
Redis cluster SSLredis_cluster_sslbooleandefault false
Redis cluster SSL verifyredis_cluster_ssl_verifybooleandefault false
Redis passwordredis_passwordstring

Stored on the engine and shown only to roles that manage this object.

Redis timeoutredis_timeoutintegerdefault 1000
at least 1 · in milliseconds
Redis keepalive poolredis_keepalive_poolintegerdefault 100
at least 1
Redis keepalive timeoutredis_keepalive_timeoutintegerdefault 10000
at least 1000 · in milliseconds
No delaynodelaybooleandefault false
Rejected coderejected_codeintegerdefault 503
200 to 599
Rejected messagerejected_msgstring
at least 1 character
Allow degradationallow_degradationbooleandefault false

Every plugin also has Enabled, Priority, Filter, Error response and Pre-function: see Plugin execution settings.

G8 dev · Apache APISIX® 3.19.0
Apache, Apache APISIX and APISIX are trademarks of The Apache Software Foundation.
Facts
Category
Traffic
Add it to
Route, Service, Consumer, Consumer group, Global rule, Plugin config
Engine plugin
limit-req
Priority
1001