Skip to content

fix: share rate-limit counters across routes with matching groupId (#463) - #468

Open
SameRainbows wants to merge 1 commit into
fastify:mainfrom
SameRainbows:fix/group-id-counter-sharing
Open

SameRainbows wants to merge 1 commit into
fastify:mainfrom
SameRainbows:fix/group-id-counter-sharing

Conversation

@SameRainbows

@SameRainbows SameRainbows commented Nov 1, 2026 •

Copy link
Copy Markdown

Fixes #463

Description

When routes configure a groupId, the group identifier is appended to the rate-limit key, but each route previously received a distinct storage partition:

  • In LocalStore.prototype.child, a new LocalStore instance was created with a fresh LRU cache per route, meaning counters on identical keys across different routes never collided.
  • In RedisStore.prototype.child, the namespace was hardcoded to routeOptions.routeInfo.method + routeOptions.routeInfo.url, prefixing the route before the key.

As a result, N routes in the same group each allowed the full max quota, rather than sharing a single quota as intended.

Changes

  • In LocalStore.prototype.child: when routeOptions.groupId is provided, reuse the parent store's LRU cache so matching group keys collide as expected.
  • In RedisStore.prototype.child: when routeOptions.groupId is provided, use the group identifier as the key prefix namespace instead of method + URL.
  • Both stores preserve the existing per-route behavior when no groupId is present.
  • Added regression tests in test/group-rate-limit.test.js verifying shared group counters, independent counters without groupId, and RedisStore child namespacing.
  • Added Redis integration coverage in test/redis-rate-limit.test.js verifying shared counters when Redis is running.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

groupId does not group routes: each route in a group gets the full max

1 participant