Skip to main content

Version: 3.3.0

Apply Rate Limiting to APIs

Applying rate limiting controls the number of requests sent to your API backend. This protects your backend from too much traffic, both wanted and unwanted (web crawlers, DDoS attacks), which can result in operational inefficiencies and higher costs.

This guide walks you through applying rate limits to control the requests sent to your upstream nodes over time.

Rate Limiting

Prerequisites

  1. Install API7 Enterprise.
  2. Have a running API on the gateway group.

You should not configure rate-limiting plugins globally, as different APIs typically require different rate-limiting quotas. If you configure the same plugin globally (in a global rule) and locally (in a route), the API7 Gateway executes both plugin instances sequentially.

Apply Rate Limiting for a Single Route

Limit Request Count

This section configures a route with rate limiting to only allow 3 requests in 60 seconds. When the limit is exceeded, a 429 status code is returned to the consumer.

  1. Select Published Services of your gateway group from the side navigation bar, then click the service you want to modify, for example, httpbin with version 1.0.0.
  2. Under the published service, select Routes from the side navigation bar.
  3. Select your target route, for example, get-ip.
  4. In the Plugin field, click Enable Plugin.
  5. Search for the limit-count plugin, then click Enable.
  6. In the dialog box, do the following:
  • Add the following configuration to the JSON Editor:

    {
    "count": 3,
    "time_window": 60,
    "key_type": "var",
    "key": "remote_addr",
    "rejected_code": 429,
    "rejected_msg": "Too many requests",
    "policy": "local",
    "allow_degradation": false,
    "show_limit_quota_header": true
    }

If you want to reference from Secret Provider, see Reference Secrets in HashiCorp Vault and Reference Secrets in AWS Secrets Manager, and use the following configuration with secret instead:

{
"count": 3,
"time_window": 60,
"key_type": "var",
"key": "remote_addr",
"rejected_code": 429,
"rejected_msg": "Too many requests",
"policy": "redis",
"redis_host": "127.0.0.1",
"redis_port": 6379,
"redis_username": "$secret://vault/my-vault/redis/username",
"redis_password": "$secret://vault/my-vault/redis/password",
"redis_database": 1,
"redis_timeout": 1001,
"allow_degradation": false,
"show_limit_quota_header": true
}
  • Click Enable.

Below is an interactive demo that provides a hands-on introduction to limiting request numbers. You will gain a better understanding of how to use it in API7 Enterprise by clicking and following the steps.

Validate

To validate, send five consecutive requests:

resp=$(seq 5 | xargs -I{} curl "http://127.0.0.1:9080/ip" -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": $count_200, "429": $count_429

You should see the following response, showing that out of the 5 requests, 3 requests were successful (status code 200) while the others were rejected (status code 429).

200:    3, 429:    2

Limit Requests per Second

This section configures a route with rate-limiting to only allow 1 request per second. When the number of requests per second is between 1 and 3 they will be delayed/throttled. When the number of requests per second is more than 3, a 429 status code is returned.

  1. Select Published Services of your gateway group from the side navigation bar, then select the service you want to modify, for example, httpbin with version 1.0.0.
  2. Under the published service, select Routes from the side navigation bar.
  3. Select your target route, for example, get-ip.
  4. In the Plugin field, click Enable Plugin.
  5. Search for the limit-req plugin, then click Enable.
  6. In the dialog box, do the following:
  • Add the following configuration to the JSON Editor:

    {
    "rate": 1,
    "burst": 2,
    "key_type": "var",
    "key": "remote_addr",
    "rejected_code": 429,
    "rejected_msg": "Requests are too frequent, please try again later."
    }
    `

  • Click Enable.

Validate

To validate, send three requests to the route:

resp=$(seq 3 | xargs -I{} curl -i "http://127.0.0.1:9080/ip" -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 

Update burst in the plugin configuration to 0, then send three requests to the route:

resp=$(seq 3 | xargs -I{} curl -i "http://127.0.0.1:9080/ip" -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

Rate Limit with Consumers

The following example demonstrates how you can configure different rate limiting policies by regular and anonymous consumers, where the anonymous consumer does not need to authenticate and has less quotas. While this example uses Key Auth Plugin for authentication, the anonymous consumer can also be configured with Basic Auth Plugin, JWT Auth Plugin, and HMAC Auth Plugin.

Add a Regular Consumer

Create a regular consumer Alice with key authentication credential, and configure the Limit Count Plugin to allow for a quota of 3 within a 60-second window:

  1. Select Consumers of your gateway group from the side navigation bar.
  2. Click Add Consumer.
  3. From the dialog box, do the following:
  • In the Name field, enter Alice.
  • Click Add.
  1. Under the Credentials tab, click Add Key Authentication Credential.
  2. From the dialog box, do the following:
  1. Got to the Plugins tab, click Enable Plugin.
  2. Search for the limit-count plugin, then click Enable.
  3. In the dialog box, do the following:
  • Add the following configuration to the JSON Editor:

    {
    "count": 3,
    "time_window": 60,
    "key_type": "var",
    "key": "remote_addr",
    "rejected_code": 429,
    "rejected_msg": "Too many requests",
    "policy": "local",
    "allow_degradation": false,
    "show_limit_quota_header": true
    }
  • Click Enable.

Add an Anonymous Consumer

Create an anonymous consumer anonymous and configure the Limit Count Plugin to allow for a quota of 1 within a 60-second window:

  1. Select Consumers of your gateway group from the side navigation bar.
  2. Click Add Consumer.
  3. From the dialog box, do the following:
  • In the Name field, enter anonymous.
  • Click Add.
  1. Got to the Plugins tab, click Enable Plugin.
  2. Search for the limit-count plugin, then click Enable.
  3. In the dialog box, do the following:
  • Add the following configuration to the JSON Editor:

    {
    "count": 1,
    "time_window": 60,
    "key_type": "var",
    "key": "remote_addr",
    "rejected_code": 429,
    "rejected_msg": "Too many requests",
    "policy": "local",
    "allow_degradation": false,
    "show_limit_quota_header": true
    }
  • Click Enable.

Configure Route

Create a route and configure the Key Auth Plugin to accept anonymous consumer anonymous from bypassing the authentication:

  1. Select Published Services of your gateway group from the side navigation bar, then click the service you want to modify, for example, httpbin with version 1.0.0.
  2. Under the published service, select Routes from the side navigation bar.
  3. Select your target route, for example, get-ip.
  4. In the Plugin field, click Enable Plugin.
  5. Search for the key-auth plugin, then click Enable.
  6. In the dialog box, do the following:
  • Add the following configuration to the JSON Editor:

    {
    "anonymous_consumer": "anonymous"
    }
  • Click Enable.

Validate

To validate, send five consecutive requests with Alice's key:

resp=$(seq 5 | xargs -I{} curl "http://127.0.0.1:9080/ip" -H 'apikey: alice-key' -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": $count_200, "429": $count_429

You should see the following response, showing that out of the 5 requests, 3 requests were successful (status code 200) while the others were rejected (status code 429).

200:    3, 429:    2

Send five anonymous requests:

resp=$(seq 5 | xargs -I{} curl "http://127.0.0.1:9080/ip" -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": $count_200, "429": $count_429

You should see the following response, showing that only one request was successful:

200:    1, 429:    4

Additional Resources


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 PTE. LTD 2019 – 2024. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the

Apache Software Foundation