Skip to content

ratelimit: token windows admit one extra request when usage lands exactly on the limit #950

Description

@jarvis9443

Description

Token-window admission checks in both backends admit a request while the committed count is exactly at the limit, and reject only when it is strictly over:

  • memory: FixedWindowCounter::is_exceeded (crates/aisix-ratelimit/src/window.rs) — if self.count > limit
  • Redis: the acquire script's token loop (crates/aisix-ratelimit/src/store/redis.rs) — if cur > limit

Token limiting is post-paid (check at admission, commit actual usage after the response), so crossing the cap by one in-flight response is inherent. But the strict > adds an avoidable case: a caller whose committed usage lands on the cap exactly (count == limit, budget fully consumed) still gets one more request admitted, overshooting by up to a full response beyond the crossing that post-paid semantics already implies.

This applies uniformly to every token window (tpm, tpd; policy-derived and key-level alike) — it is not specific to any one window and predates #771/#949, which only added a new window over the same counters.

Proposal

Flip both comparisons to >= ("budget fully consumed ⇒ stop admitting") in the same change, with an exact-limit regression case per backend — e.g. cap 10, upstream reports exactly 10, the next request must be 429. Request counters are pre-paid (would_be > limit with the increment included) and are already exact; they need no change.

Both backends must move together (memory ↔ redis swap must not change observable limits).

Priority

Low — one-request overshoot at an exact boundary; found during review of #949.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Long-tail integrations — backlogenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions