Project: APISIX (Orchestration & Management / API Gateway)
File: limit-req.md

title: limit-req keywords: Apache APISIX API Gateway Limit Request limit-req description: The limit-req Plugin limits the number of requests to your service using the leaky bucket algorithm. <!-- --> The `limit-req` Plugin limits the number of requests to your service using the algorithm. | Name | Type | Required | Default | Valid values | Description | |-||-||-|-| | rate | integer | True | | rate > 0 | Threshold for number of requests per second. Requests exceeding this rate (and below `burst`) will be delayed to match this rate. | | burst | integer | True | | burst >= 0 | Number of additional requests allowed to be delayed per second. If the number of requests exceeds this hard limit, they will get rejected immediately. | | keytype | string | False | "var" | ["var", "varcombination"] | Type of user specified key to use. | | key | string | True | | ["remoteaddr", "serveraddr", "httpxrealip", "httpxforwardedfor", "consumername"] | User specified key to base the request limiting on. If the `keytype` attribute is set to `var`, the key will be treated as a name of variable, like `remoteaddr` or `consumername`. If the `keytype` is set to `varcombination`, the key will be a combination of variables, like `$remoteaddr $consumername`. If the value of the key is empty, `remote_addr` will be set as the default key. | | rejected_code | integer | False | 503 | [200,...,599] | HTTP status code returned when the requests exceeding the threshold are rejected. | | rejected_msg | string | False | | non-empty | Body of the response returned when the requests exceeding the threshold are rejected. | | nodelay | boolean | False | false | | If set to `true`, requests within the burst threshold would not be delayed. | | allow_degradation | boolean | False | false | | When set to `true` enables Plugin degradation when the Plugin is temporarily unavailable and allows requests to continue. | | policy | string | False | "local" | ["local", "redis", "redis-cluster"] | Rate-limiting policies to use for retrieving and increment the limit count. When set to `local` the counters will be locally stored in memory on the node. When set to `redis` counters are stored on a Redis server and will be shared across the nodes. It is done usually for global speed limiting, and setting to `redis-cluster` uses a Redis cluster instead of a single instance. | | redis_host | string | required when `policy` is `redis` | | | Address of the Redis

Used when the `policy` attribute is set to `redis`. | | redis_port | integer | False | 6379 | [1,...] | Port of the Redis server. Used when the `policy` attribute is set to `redis`. | | redisusername | string | False | | | Username for Redis authentication if Redis ACL is used (for Redis version >= 6.0). If you use the legacy authentication method `requirepass` to configure Redis password, configure only the `redispassword`. Used when the `policy` is set to `redis`. | | redis_password | string | False | | | Password for Redis authentication. Used when the `policy` is set to `redis` or `redis-cluster`. | | redis_ssl | boolean | False | false | | If set to `true`, then uses SSL to connect to redis instance. Used when the `policy` attribute is set to `redis`. | | redissslverify | boolean | False | false | | If set to `true`, then verifies the validity of the server SSL certificate. Used when the `policy` attribute is set to `redis`. See . | | redisdatabase | integer | False | 0 | redisdatabase >= 0 | Selected database of the Redis server (for single instance operation or when using Redis cloud with a single entrypoint). Used when the `policy` attribute is set to `redis`. | | redis_timeout | integer | False | 1000 | [1,...] | Timeout in milliseconds for any command submitted to the Redis server. Used when the `policy` attribute is set to `redis` or `redis-cluster`. | | redisclusternodes | array | required when `policy` is `redis-cluster` | | | Addresses of Redis cluster nodes. Used when the `policy` attribute is set to `redis-cluster`. | | redisclustername | string | required when `policy` is `redis-cluster` | | | Name of the Redis cluster service nodes. Used when the `policy` attribute is set to `redis-cluster`. | | redisclusterssl | boolean | False | false | | If set to `true`, then uses SSL to connect to redis-cluster. Used when the `policy` attribute is set to `redis-cluster`. | | redisclusterssl_verify | boolean | False | false | | If set to `true`, then verifies the validity of the server SSL certificate. Used when the `policy` attribute is set to `redis-cluster`. | You can enable the Plugin on a Route as shown below: :::note You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command: ```bash adminkey=$(yq '.deployment.admin.adminkey[0].key' conf/config.yaml | sed 's/"//g') ``` ::: ```shell curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' { "methods": ["GET"], "uri":

"plugins": { "limit-req": { "rate": 1, "burst": 2, "rejected_code": 503, "key_type": "var", "key": "remote_addr" } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:9001": 1 } } }' ``` You can also configure the `keytype` to `varcombination` as shown: ```json { "methods": ["GET"], "uri": "/index.html", "plugins": { "limit-req": { "rate": 1, "burst": 2, "rejected_code": 503, "keytype": "varcombination", "key": "$consumername $remoteaddr" } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:9001": 1 } } } ``` You can also configure the Plugin on specific consumers to limit their requests. First, you can create a Consumer and enable the `limit-req` Plugin on it: ```shell curl http://127.0.0.1:9180/apisix/admin/consumers -H "X-API-KEY: $admin_key" -X PUT -d ' { "username": "consumer_jack", "plugins": { "key-auth": { "key": "auth-jack" }, "limit-req": { "rate": 1, "burst": 3, "rejected_code": 403, "key": "consumer_name" } } }' ``` In this example, the Plugin is used to authenticate the Consumer. Next, create a Route and enable the `key-auth` Plugin: ```shell curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' { "methods": ["GET"], "uri": "/index.html", "plugins": { "key-auth": { "key": "auth-jack" } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:1980": 1 } } }' ``` Once you have configured the Plugin as shown above, you can test it out. The above configuration limits to 1 request per second. If the number of requests is greater than 1 but less than 3, a delay will be added. And if the number of requests per second exceeds 3, it will be rejected. Now if you send a request: ```shell curl -i http://127.0.0.1:9080/index.html ``` For authenticated requests: ```shell curl -i http://127.0.0.1:9080/index.html -H 'apikey: auth-jack' ``` If you exceed the limit, you will receive a response with a 503 code: ```html HTTP/1.1 503 Service Temporarily Unavailable Content-Type: text/html Content-Length: 194 Connection: keep-alive Server: APISIX web server <html> <head><title>503 Service Temporarily Unavailable</title></head> <body> <center><h1>503 Service Temporarily Unavailable</h1></center> <hr><center>openresty</center> </body> </html> ``` You can set a custom rejected message by configuring the `rejected_msg` attribute. You will then receive a response like: ```shell HTTP/1.1 503 Service Temporarily Unavailable Content-Type: text/html Content-Length: 194 Connection: keep-alive Server: APISIX web server {"error_msg":"Requests are too frequent, please try again later."} ``` To remove the `limit-req` Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect. ```shell curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' { "methods": ["GET"], "uri": "/index.html", "id": 1, "plugins": { }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:1980": 1 } } }' ``` Similarly for removing the Plugin from a Consumer: ```shell curl http://127.0.0.1:9180/apisix/admin/consumers -H "X-API-KEY: $admin_key" -X PUT -d ' { "username": "consumer_jack", "plugins": { "key-auth": { "key": "auth-jack" } } }' ```