Skip to content

Commit 8e6f162

Browse files
committed
chore: update docs about sliding window
Signed-off-by: Sihyeon Jang <[email protected]>
1 parent 03e4161 commit 8e6f162

File tree

2 files changed

+70
-4
lines changed

2 files changed

+70
-4
lines changed

docs/en/latest/plugins/limit-count.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ keywords:
44
- Apache APISIX
55
- API Gateway
66
- Limit Count
7-
description: The limit-count plugin uses a fixed 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.
7+
description: The limit-count plugin limits the rate of requests by the number of requests within a given time interval. It supports both fixed window and sliding window behaviors. Requests exceeding the configured quota will be rejected.
88
---
99

1010
<!--
@@ -32,7 +32,12 @@ description: The limit-count plugin uses a fixed window algorithm to limit the r
3232

3333
## Description
3434

35-
The `limit-count` plugin uses a fixed 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.
35+
The `limit-count` plugin limits the rate of requests by the number of requests within a given time interval. It supports both **fixed window** and **sliding window** behaviors.
36+
37+
- When `window_type` is `fixed` (default), the plugin uses a fixed window algorithm.
38+
- When `window_type` is `sliding`, and the `policy` is `redis` or `redis-cluster`, the plugin enforces an exact **N requests per rolling time window** using a sliding window algorithm.
39+
40+
Requests exceeding the configured quota will be rejected.
3641

3742
You may see the following rate limiting headers in the response:
3843

@@ -46,6 +51,7 @@ You may see the following rate limiting headers in the response:
4651
| ----------------------- | ------- | ----------------------------------------- | ------------- | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
4752
| count | integer | True | | > 0 | The maximum number of requests allowed within a given time interval. |
4853
| time_window | integer | True | | > 0 | The time interval corresponding to the rate limiting `count` in seconds. |
54+
| window_type | string | False | fixed | ["fixed","sliding"] | The window behavior type. `fixed` uses a fixed window algorithm. `sliding` uses a sliding window algorithm to enforce an exact number of requests per rolling window. `sliding` is only supported when `policy` is `redis` or `redis-cluster`. |
4955
| key_type | string | False | var | ["var","var_combination","constant"] | The type of key. If the `key_type` is `var`, the `key` is interpreted a variable. If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. If the `key_type` is `constant`, the `key` is interpreted as a constant. |
5056
| key | string | False | remote_addr | | The key to count requests by. If the `key_type` is `var`, the `key` is interpreted a variable. The variable does not need to be prefixed by a dollar sign (`$`). If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. All variables should be prefixed by dollar signs (`$`). For example, to configure the `key` to use a combination of two request headers `custom-a` and `custom-b`, the `key` should be configured as `$http_custom_a $http_custom_b`. If the `key_type` is `constant`, the `key` is interpreted as a constant value. |
5157
| rejected_code | integer | False | 503 | [200,...,599] | The HTTP status code returned when a request is rejected for exceeding the threshold. |
@@ -401,6 +407,33 @@ You should see an `HTTP/1.1 200 OK` response with the corresponding response bod
401407

402408
Send the same request to a different APISIX instance within the same 30-second time interval, you should receive an `HTTP/1.1 429 Too Many Requests` response, verifying routes configured in different APISIX nodes share the same quota.
403409

410+
### Performance considerations (sliding window)
411+
412+
When `window_type` is set to `sliding` and the `policy` is `redis` or `redis-cluster`, this Plugin uses a Redis ZSET to store timestamps for recent requests (a sliding log).
413+
414+
Roughly, the memory usage for sliding window per Redis instance can be approximated as:
415+
416+
\[
417+
\text{Memory} \approx K \times C \times B
418+
\]
419+
420+
Where:
421+
422+
- \(K\): number of active keys that receive traffic within a `time_window`
423+
- \(C\): `count` (maximum requests allowed per key within the window)
424+
- \(B\): bytes per ZSET entry (timestamp + member + metadata). A conservative estimate is around 100 bytes.
425+
426+
For example:
427+
428+
- \(K = 10{,}000\), \(C = 50\), \(B \approx 100\) → about 50 MB
429+
- \(K = 100{,}000\), \(C = 100\), \(B \approx 100\) → about 1 GB
430+
431+
In practice, you should:
432+
433+
- Monitor Redis memory and CPU when enabling sliding windows.
434+
- Prefer relatively small `count` values (tens to low hundreds) for keys with high QPS.
435+
- Consider using `window_type = "fixed"` (or `limit-req`) for very high throughput keys with large `count` or very high key cardinality.
436+
404437
### Rate Limit with Anonymous Consumer
405438

406439
does not need to authenticate and has less quotas. While this example uses [`key-auth`](./key-auth.md) for authentication, the anonymous Consumer can also be configured with [`basic-auth`](./basic-auth.md), [`jwt-auth`](./jwt-auth.md), and [`hmac-auth`](./hmac-auth.md).

docs/zh/latest/plugins/limit-count.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ keywords:
55
- API 网关
66
- Limit Count
77
- 速率限制
8-
description: limit-count 插件使用固定窗口算法,通过给定时间间隔内的请求数量来限制请求速率。超过配置配额的请求将被拒绝。
8+
description: limit-count 插件通过给定时间间隔内的请求数量来限制请求速率,支持固定窗口和滑动窗口两种行为。超过配置配额的请求将被拒绝。
99
---
1010

1111
<!--
@@ -33,7 +33,12 @@ description: limit-count 插件使用固定窗口算法,通过给定时间间
3333

3434
## 描述
3535

36-
`limit-count` 插件使用固定窗口算法,通过给定时间间隔内的请求数量来限制请求速率。超过配置配额的请求将被拒绝。
36+
`limit-count` 插件通过给定时间间隔内的请求数量来限制请求速率,支持 **固定窗口****滑动窗口** 两种行为。
37+
38+
-`window_type``fixed`(默认)时,插件使用固定窗口算法。
39+
-`window_type``sliding``policy``redis``redis-cluster` 时,插件使用滑动窗口算法,在滚动时间窗口内精确限制请求次数。
40+
41+
超过配置配额的请求将被拒绝。
3742

3843
您可能会在响应中看到以下速率限制标头:
3944

@@ -47,6 +52,7 @@ description: limit-count 插件使用固定窗口算法,通过给定时间间
4752
| ------------------- | ------- | ---------- | ------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
4853
| count | integer || | > 0 | 给定时间间隔内允许的最大请求数。 |
4954
| time_window | integer || | > 0 | 速率限制 `count` 对应的时间间隔(以秒为单位)。 |
55+
| window_type | string || fixed | ["fixed","sliding"] | 窗口行为类型。`fixed` 使用固定窗口算法;`sliding` 使用滑动窗口算法,在滚动时间窗口内精确限制请求次数。仅当 `policy``redis``redis-cluster` 时才支持 `sliding`|
5056
| key_type | string || var | ["var","var_combination","constant"] | key 的类型。如果`key_type``var`,则 `key` 将被解释为变量。如果 `key_type``var_combination`,则 `key` 将被解释为变量的组合。如果 `key_type``constant`,则 `key` 将被解释为常量。 |
5157
| key | string || remote_addr | | 用于计数请求的 key。如果 `key_type``var`,则 `key` 将被解释为变量。变量不需要以美元符号(`$`)为前缀。如果 `key_type``var_combination`,则 `key` 会被解释为变量的组合。所有变量都应该以美元符号 (`$`) 为前缀。例如,要配置 `key` 使用两个请求头 `custom-a``custom-b` 的组合,则 `key` 应该配置为 `$http_custom_a $http_custom_b`。如果 `key_type``constant`,则 `key` 会被解释为常量值。|
5258
| rejection_code | integer || 503 | [200,...,599] | 请求因超出阈值而被拒绝时返回的 HTTP 状态代码。|
@@ -402,6 +408,33 @@ curl -i "http://127.0.0.1:9080/get"
402408

403409
在相同的 30 秒时间间隔内向不同的 APISIX 实例发送相同的请求,您应该会收到一个 `HTTP/1.1 429 Too Many Requests` 响应,验证在不同 APISIX 节点中配置的路由是否共享相同的配额。
404410

411+
### 性能注意事项(滑动窗口)
412+
413+
`window_type` 配置为 `sliding``policy``redis``redis-cluster` 时,`limit-count` 会使用 Redis ZSET 作为滑动日志,按时间戳存储最近的请求记录。
414+
415+
大致的内存占用可以近似为:
416+
417+
\[
418+
\text{内存} \approx K \times C \times B
419+
\]
420+
421+
其中:
422+
423+
- \(K\):在一个 `time_window` 内实际接收到流量的 key 数量
424+
- \(C\)`count`(每个 key 在窗口内允许的最大请求数)
425+
- \(B\):每个 ZSET 元素占用的字节数(时间戳 + member 字符串 + 元数据,保守估计约为 100 字节)
426+
427+
例如:
428+
429+
- \(K = 10{,}000\), \(C = 50\), \(B \approx 100\) → 内存约 50 MB
430+
- \(K = 100{,}000\), \(C = 100\), \(B \approx 100\) → 内存约 1 GB
431+
432+
实际使用时建议:
433+
434+
- 开启 `window_type = "sliding"` 时监控 Redis 的内存和 CPU 使用情况;
435+
- 对高 QPS 的 key,优先使用相对较小的 `count`(几十到一两百级别);
436+
- 对于 `count` 很大、key 数量非常多或单 key 负载极高的场景,优先考虑 `window_type = "fixed"` 或使用 `limit-req` 插件来实现速率限制。
437+
405438
### 使用匿名消费者进行速率限制
406439

407440
以下示例演示了如何为常规和匿名消费者配置不同的速率限制策略,其中匿名消费者不需要进行身份验证并且配额较少。虽然此示例使用 [`key-auth`](./key-auth.md) 进行身份验证,但匿名消费者也可以使用 [`basic-auth`](./basic-auth.md)[`jwt-auth`](./jwt-auth.md)[`hmac-auth`](./hmac-auth.md) 进行配置。

0 commit comments

Comments
 (0)