Skip to main content

limit-count-advanced

The limit-count-advanced plugin uses a fixed or sliding window algorithm to limit the rate of requests by the number of requests within a given time interval. Requests exceeding the configured quota will be rejected.

Specifically:

  • Fixed window algorithm tracks requests in non-overlapping time intervals. If the request count exceeds the quota in any interval, excess requests are immediately rejected until the next time window begins.
  • Sliding window algorithm tracks requests in overlapping intervals, smoothing out the rate limit by counting recent requests within the last configured time period, regardless of when the interval began. This method reduces traffic spikes and is more effective at evenly distributing requests over time.

Additionally, you may also see the following rate limiting response headers, the name of which can be customized using plugin metadata:

  • X-RateLimit-Limit: the total quota
  • X-RateLimit-Remaining: the remaining quota
  • X-RateLimit-Reset: number of seconds left for the counter to reset

Occasionally, you might observe a small negative value for the X-RateLimit-Remaining. This is acceptable as the sliding window algorithm is an approximation.

Examples

The plugin supports sliding window algorithm in addition to the limit-count plugin features. Please refer to limit-count plugin for fixed window examples, which can also be configured in limit-count-advanced.

The examples below demonstrate how you can use limit-count-advanced to rate limit using sliding window algorithm.

Rate Limit with Counter in APISIX

The following example demonstrates how you can configure limit-count-advanced to use the sliding window algorithm for rate limiting on a route, using the counter in APISIX. Note that each APISIX instance has its own counter and independent quota. If you have multiple APISIX instances that need to share the same quota, please see the next example.

Create a route with limit-count-advanced plugin that allows for a quota of 5 within a 10-second sliding window 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-count-sliding-route",
"uri": "/get",
"plugins": {
"limit-count-advanced": {
"count": 5,
"time_window": 10,
"rejected_code": 429,
"key_type": "var",
"key": "remote_addr",
"window_type": "sliding"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'

Generate 7 requests to the route every other second:

for i in $(seq 7); do
(curl -I "http://127.0.0.1:9080/get" &)
sleep 1
done

You should receive HTTP/1.1 200 OK responses for most requests, with the remainder being HTTP 429 Too Many Requests responses. The specific number rejected depends on when first request is sent.

Share Quota Among APISIX Nodes with a Redis Server

The following example demonstrates the rate limiting of requests across multiple APISIX nodes with a Redis server using the sliding window algorithm, such that different APISIX nodes share the same rate limiting quota.

On each APISIX instance, create a route with the following configurations. Adjust the address of the Admin API accordingly.

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-count-sliding-route",
"uri": "/get",
"plugins": {
"limit-count-advanced": {
"count": 1,
"time_window": 30,
"rejected_code": 429,
"key": "remote_addr",
"policy": "redis",
"redis_host": "192.168.xxx.xxx",
"redis_port": 6379,
"redis_password": "p@ssw0rd",
"redis_database": 1,
"window_type": "sliding",
"sync_interval": 0.2
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'

policy: set to redis to use a Redis instance for rate limiting.

redis_host: set to Redis instance IP address.

redis_port: set to Redis instance listening port.

redis_password: set to the password of the Redis instance, if any.

redis_database: set to the database number in the Redis instance.

window_type: set the window type to sliding window.

sync_interval: set the synchronization interval (optional).

Generate 7 requests to the route every other second:

for i in $(seq 7); do
(curl -I "http://127.0.0.1:9080/get" &)
sleep 1
done

You should receive HTTP/1.1 200 OK responses for most requests, with the remainder being HTTP 429 Too Many Requests responses. The specific number rejected depends on when first request is sent. This verifies routes configured in different APISIX nodes share the same quota.

Share Quota Among APISIX Nodes with a Redis Cluster

The following example demonstrates how you can configure limit-count-advanced to use the sliding window algorithm and apply the same quota across multiple APISIX nodes, such that different APISIX nodes share the same rate limiting quota.

Ensure that your Redis instances are running in cluster mode. A minimum of two nodes are required for the limit-count-advanced plugin configurations.

On each APISIX instance, create a route with the following configurations. Adjust the address of the Admin API accordingly.

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "limit-count-route",
"uri": "/get",
"plugins": {
"limit-count-advanced": {
"count": 1,
"time_window": 30,
"rejected_code": 429,
"key": "remote_addr",
"policy": "redis-cluster",
"redis_cluster_nodes": [
"192.168.xxx.xxx:6379",
"192.168.xxx.xxx:16379"
],
"redis_password": "p@ssw0rd",
"redis_cluster_name": "redis-cluster-1",
"redis_cluster_ssl": true,
"window_type": "sliding",
"sync_interval": 0.2
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'

policy: set to redis-cluster to use a Redis cluster for rate limiting.

redis_cluster_nodes: set to Redis node addresses in the Redis cluster.

redis_password: set to the password of the Redis cluster, if any.

redis_cluster_name: set to the Redis cluster name.

redis_cluster_ssl: enable SSL/TLS communication with Redis cluster.

window_type: set the window type to sliding window.

sync_interval: set the synchronization interval (optional).

Generate 7 requests to the route every other second:

for i in $(seq 7); do
(curl -I "http://127.0.0.1:9080/get" &)
sleep 1
done

You should receive HTTP/1.1 200 OK responses for most requests, with the remainder being HTTP 429 Too Many Requests responses. The specific number rejected depends on when first request is sent. This verifies routes configured in different APISIX nodes share the same quota.

Customize Rate Limiting Headers

The following example demonstrates how you can use plugin metadata to customize the rate limiting response header names, which are by default X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.

Configure the plugin metadata for this plugin and update the headers:

curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/limit-count" -X PUT -d '
{
"log_format": {
"limit_header": "X-Custom-RateLimit-Limit",
"remaining_header": "X-Custom-RateLimit-Remaining",
"reset_header": "X-Custom-RateLimit-Reset"
}
}'

Create a route with limit-count-advanced plugin that allows for a quota of 1 within a 30-second window 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-count-advanced-route",
"uri": "/get",
"plugins": {
"limit-count-advanced": {
"count": 1,
"time_window": 30,
"rejected_code": 429,
"key_type": "var",
"key": "remote_addr",
"window_type": "sliding"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'

Send a request to verify:

curl -i "http://127.0.0.1:9080/get"

You should receive an HTTP/1.1 200 OK response and see the following headers:

X-Custom-RateLimit-Limit: 1
X-Custom-RateLimit-Remaining: 0
X-Custom-RateLimit-Reset: 28

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