limit-req
The limit-req
plugin uses the leaky bucket algorithm to rate limit the number of the requests and allow for throttling.
Examples
The examples below demonstrate how you can configure limit-req
in different scenarios.
Apply Rate Limiting by Remote Address
The following example demonstrates the rate limiting of HTTP requests by a single variable, remote_addr
.
Create a route with limit-req
plugin that allows for 1 QPS per remote address:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '
{
"id": "limit-req-route",
"uri": "/get",
"plugins": {
"limit-req": {
"rate": 1,
"burst": 0,
"key": "remote_addr",
"key_type": "var",
"rejected_code": 429,
"nodelay": true
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
❶ rate
: limit the QPS to 1.
❷ key
: set to remote_addr
to apply rate limiting quota by remote address and consumer.
❸ key_type
: set to var
to interpret the key
as a variable.
Send a request to verify:
curl -i "http://127.0.0.1:9080/get"
You should see an HTTP/1.1 200 OK
response.
The request has consumed all the quota allowed for the time window. If you send the request again within the same second, you should receive an HTTP/1.1 429 Too Many Requests
response, indicating the request surpasses the quota threshold.
Implement API Throttling
The following example demonstrates how to configure burst
to allow overrun of the rate limiting threshold by the configured value and achieve request throttling. You will also see a comparison against when throttling is not implemented.
Create a route with limit-req
plugin that allows for 1 QPS per remote address, with a burst
of 1:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-req-route",
"uri": "/get",
"plugins": {
"limit-req": {
"rate": 1,
"burst": 1,
"key": "remote_addr",
"rejected_code": 429
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
❶ burst
: allow for 1 request exceeding the rate
to be delayed for processing.
Generate three requests to the route:
resp=$(seq 3 | xargs -I{} curl -i "http://127.0.0.1:9080/get" -o /dev/null -s -w "%{http_code}\n") && \
count_200=$(echo "$resp" | grep "200" | wc -l) && \
count_429=$(echo "$resp" | grep "429" | wc -l) && \
echo "200 responses: $count_200 ; 429 responses: $count_429"
You are likely to see that all three requests are successful:
200 responses: 3 ; 429 responses: 0
To see the effect without burst
, update burst
to 0 or set nodelay
to true
as follows:
curl "http://127.0.0.1:9180/apisix/admin/routes/limit-req-route" -X PATCH \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"plugins": {
"limit-req": {
"nodelay": true
}
}
}'
Generate three requests to the route again:
resp=$(seq 3 | xargs -I{} curl -i "http://127.0.0.1:9080/get" -o /dev/null -s -w "%{http_code}\n") && \
count_200=$(echo "$resp" | grep "200" | wc -l) && \
count_429=$(echo "$resp" | grep "429" | wc -l) && \
echo "200 responses: $count_200 ; 429 responses: $count_429"
You should see a response similar to the following, showing requests surpassing the rate have been rejected:
200 responses: 1 ; 429 responses: 2
Apply Rate Limiting by Remote Address and Consumer Name
The following example demonstrates the rate limiting of requests by a combination of variables, remote_addr
and consumer_name
.
Create a route with limit-req
plugin that allows for 1 QPS per remote address and for each consumer.
Create a consumer john
:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "john"
}'
Create key-auth
credential for the consumer:
curl "http://127.0.0.1:9180/apisix/admin/consumers/john/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-john-key-auth",
"plugins": {
"key-auth": {
"key": "john-key"
}
}
}'
Create a second consumer jane
:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "jane"
}'
Create key-auth
credential for the consumer:
curl "http://127.0.0.1:9180/apisix/admin/consumers/jane/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-jane-key-auth",
"plugins": {
"key-auth": {
"key": "jane-key"
}
}
}'
Create a route with key-auth
and limit-req
plugins:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-req-route",
"uri": "/get",
"plugins": {
"key-auth": {},
"limit-req": {
"rate": 1,
"burst": 0,
"key": "$remote_addr $consumer_name",
"key_type": "var_combination",
"rejected_code": 429
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
❶ key-auth
: enable key authentication on the route.
❷ key
: set to $remote_addr $consumer_name
to apply rate limiting quota by remote address and consumer.
❸ key_type
: set to var_combination
to interpret the key
is as a combination of variables.
Send two requests simultaneously, each for one consumer:
curl -i "http://127.0.0.1:9080/get" -H 'apikey: jane-key' & \
curl -i "http://127.0.0.1:9080/get" -H 'apikey: john-key' &
You should receive HTTP/1.1 200 OK
for both requests, indicating the request has not exceeded the threshold for each consumer.
If you send more requests as either consumer within the same second, you should receive an HTTP/1.1 429 Too Many Requests
response.
This verifies the plugin rate limits by the combination of variables, remote_addr
and consumer_name
.