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 quotaX-RateLimit-Remaining
: the remaining quotaX-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