Skip to main content

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.


API7.ai Logo

API Management for Modern Architectures with Edge, API Gateway, Kubernetes, and Service Mesh.

Product

API7 Cloud

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN Ltd. 2019 – 2024. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the

Apache Software Foundation