Skip to content

feat(plugin): add limit-req-global — cluster-wide rate limiting - #13759

Open
lovelock wants to merge 1 commit into
apache:masterfrom
lovelock:master
Open

feat(plugin): add limit-req-global — cluster-wide rate limiting#13759
lovelock wants to merge 1 commit into
apache:masterfrom
lovelock:master

Conversation

@lovelock

Copy link
Copy Markdown

Introduces a new plugin that distributes a cluster-wide global rate across N nodes using a shared metadata-driven instance_count.

Behavior:
local_rate = global_rate / instance_count
local_burst = global_burst / instance_count

instance_count is stored in plugin_metadata, refreshed every 10s by a per-worker background timer. Defaults to 1 when metadata is unset.

Default rejected_code is 429 (Too Many Requests).

Description

Standard limit-req is per-node: N nodes each with rate=100 effectively allow N*100 req/s cluster-wide.

This plugin solves this by accepting a global_rate at the route level and computing local_rate = global_rate / instance_count per node. instance_count is configured cluster-wide via plugin_metadata, and each node's timer picks it up every 10 seconds.

The approach uses only local shared dicts (no cross-node coordination), making it efficient and avoiding single points of failure.

Which issue(s) this PR fixes:

N/A — new feature.

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible (If not, please discuss on the APISIX mailing list first)

Introduces a new plugin that distributes a cluster-wide global rate across N nodes using a shared metadata-driven instance_count.

Behavior:
  local_rate  = global_rate / instance_count
  local_burst = global_burst / instance_count

instance_count is stored in plugin_metadata, refreshed every 10s by a per-worker background timer. Defaults to 1 when metadata is unset.

Default rejected_code is 429 (Too Many Requests).

### Description

Standard limit-req is per-node: N nodes each with rate=100 effectively allow N*100 req/s cluster-wide.

This plugin solves this by accepting a global_rate at the route level and computing local_rate = global_rate / instance_count per node. instance_count is configured cluster-wide via plugin_metadata, and each node's timer picks it up every 10 seconds.

The approach uses only local shared dicts (no cross-node coordination), making it efficient and avoiding single points of failure.

#### Which issue(s) this PR fixes:

N/A — new feature.

### Checklist

- [x] I have explained the need for this PR and the problem it solves
- [x] I have explained the changes or the new features added to this PR
- [x] I have added tests corresponding to this change
- [ ] I have updated the documentation to reflect this change
- [ ] I have verified that this change is backward compatible (If not, please discuss on the [APISIX mailing list](https://github.com/apache/apisix/tree/master#community) first)
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. enhancement New feature or request plugin labels Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request plugin size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant