feat: support live reloading of individual rate limits#2469
Merged
Conversation
Move API limiter setup out of internal/api and into a dedicated internal/api/apilimiter package, then wire it into serve-time config reloads so rate limit changes are picked up without restarting the service. This change replaces the old LimiterOptions type with an apilimiter.Limiter instance passed through api.WithLimiter(...). API construction now defaults to apilimiter.New(...) when no limiter is injected, and tests are updated to use the new option-based wiring. The new apilimiter package centralizes: - construction of all ratelimit and tollbooth limiters - mapping between config/env vars and limiter fields - copy/update logic for reusing existing limiter state where possible - structured logging for limiter changes during config reload On config reload in serve(): - keep track of the previously active limiter set - call previousLim.Update(...) against the latest config - build the new API with the updated limiter set - store the new API, reload apiworker config, and retain the latest limiter for the next reload cycle This fixes the prior behavior where hot config reload rebuilt the API but kept stale limiter settings, meaning rate-limit changes were not applied until process restart. Additional ratelimit changes: - persist the original parsed conf.Rate value in conf.Rate via val - add GetRateValue() for logging/comparison purposes - extend ratelimit.Limiter with Config() so limiters can expose their backing configuration - add ratelimit.Equal(...) helper to compare limiters, configs, and rate strings consistently - store conf.Rate on BurstLimiter and IntervalLimiter and expose Config() - add String() methods to identify limiter type in tests/debug output - rename IntervalLimiter.limit to events for clarity Behavioral note: - BurstLimiter documentation now matches implementation for non-positive event counts: burst size becomes 0, so no events are allowed Tests: - update API tests to inject limiters through api.WithLimiter - update options tests to validate apilimiter.New - expand ratelimit tests to cover type identification and equality semantics - add dedicated apilimiter tests that verify only the expected fields change when each config/env-backed limiter value is modified
This comment has been minimized.
This comment has been minimized.
Contributor
Author
The view logs links end up asking to act on my behalf on github just to see the test failures, not a fan of that. When I fixed the tests it no longer re-ran tests like it use to. Is this part of the blacksmith changes or just a potential tweak needed to actions? |
fadymak
approved these changes
Apr 9, 2026
Co-authored-by: fadymak <dev@fadymak.com>
This comment has been minimized.
This comment has been minimized.
fadymak
pushed a commit
that referenced
this pull request
Apr 28, 2026
🤖 I have created a release *beep* *boop* --- ## [2.189.0](v2.188.1...v2.189.0) (2026-04-23) ### Features * add PKCE support for `/resend` ([#2401](#2401)) ([2af904a](2af904a)) * improve parallelization in github workflows and Makefile ([#2436](#2436)) ([9d0c4b3](9d0c4b3)) * **passkeys:** add CAPTCHA to options endpoint for authentication ([#2416](#2416)) ([c7b58be](c7b58be)) * support live reloading of individual rate limits ([#2469](#2469)) ([d03d796](d03d796)) ### Bug Fixes * ensure identities are returned in a consistent order across DB engines ([#2465](#2465)) ([e49a3e5](e49a3e5)) * ensure SSO providers tests are order-independent ([#2466](#2466)) ([983ade6](983ade6)) * exempt PKCE recovery sessions from require-current-password check ([#2502](#2502)) ([7f88985](7f88985)) * **indexworker:** skip index creation on OrioleDB ([#2481](#2481)) ([dd56ae9](dd56ae9)) * **passkeys:** modify the passkeys request and response shapes ([#2475](#2475)) ([2d8f2b6](2d8f2b6)) * prevent reuse of flow state ([#2483](#2483)) ([88dcb2d](88dcb2d)) * return JSON response for unmatched routes instead of plain text ([#2457](#2457)) ([7337e21](7337e21)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: supabase-releaser[bot] <223506987+supabase-releaser[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Move API limiter setup out of internal/api and into a dedicated internal/api/apilimiter package, then wire it into serve-time config reloads so rate limit changes are picked up without restarting the service.
This change replaces the old LimiterOptions type with an apilimiter.Limiter instance passed through api.WithLimiter(...). API construction now defaults to apilimiter.New(...) when no limiter is injected, and tests are updated to use the new option-based wiring.
The new apilimiter package centralizes:
On config reload in serve():
This fixes the prior behavior where hot config reload rebuilt the API but kept stale limiter settings, meaning rate-limit changes were not applied until process restart.
Additional ratelimit changes:
Behavioral note:
Tests: