fix(indexer): correct rate limiter replenish to true RPS (#355) #852

Merged
PlasticDigits merged 1 commit from local1/355-impl-rate-limiter-rps into main 2026-06-10 05:31:28 +00:00
PlasticDigits commented 2026-06-10 03:33:15 +00:00 (Migrated from gitlab.com)

Summary

Fixes #355 — tower_governor per_second(rps) replenishes one token every rps seconds, not rps tokens per second. Effective limits were burst-only then ~1 req / RPS seconds.

Changes

  • replenish_period_for_rps: Duration::from_nanos(1_000_000_000 / rps)
  • Sustained-throughput regression test in security.rs
  • Docs: dev must set both RATE_LIMIT_RPS=0 and RATE_LIMIT_LCD_HEAVY_RPS=0 to fully disable

Verification checklist

  • Rebuild/redeploy indexer
  • Rapid book polling on /trade does not 429 under normal single-user use
  • cargo test --test security rate_limit passes

Note

Medium Risk
Changes abuse-protection behavior for all API traffic (global 60 RPS and LCD-heavy 10 RPS); legitimate sustained polling should see fewer false 429s, but post-burst throughput rises to match config.

Overview
Fixes #355: tower_governor’s per_second(rps) was wired as one token every rps seconds, so after the burst drained, sustained traffic was far below the configured RPS (e.g. ~1 req/min at 60 RPS).

apply_rate_limit_layer now sets .period(replenish_period_for_rps(rps)) with 1s / rps instead of .per_second(rps), so global and LCD-heavy governors actually replenish at the intended requests-per-second. Burst size is unchanged (2 × rps).

Adds unit tests for the period math and an integration test that drains burst at 5 RPS, waits ~1.1s, and expects ~5 successes again. Docs note replenish = 1s / RPS, and that dev must set RATE_LIMIT_RPS=0 and RATE_LIMIT_LCD_HEAVY_RPS=0 to disable all governors.

Reviewed by Cursor Bugbot for commit bdfeeef671. Bugbot is set up for automated code reviews on this repo. Configure here.

## Summary Fixes #355 — `tower_governor` `per_second(rps)` replenishes one token every `rps` seconds, not `rps` tokens per second. Effective limits were burst-only then ~1 req / RPS seconds. ## Changes - `replenish_period_for_rps`: `Duration::from_nanos(1_000_000_000 / rps)` - Sustained-throughput regression test in `security.rs` - Docs: dev must set both `RATE_LIMIT_RPS=0` and `RATE_LIMIT_LCD_HEAVY_RPS=0` to fully disable ## Verification checklist - [ ] Rebuild/redeploy indexer - [ ] Rapid book polling on `/trade` does not 429 under normal single-user use - [ ] `cargo test --test security rate_limit` passes <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes abuse-protection behavior for all API traffic (global 60 RPS and LCD-heavy 10 RPS); legitimate sustained polling should see fewer false 429s, but post-burst throughput rises to match config. > > **Overview** > Fixes **#355**: `tower_governor`’s `per_second(rps)` was wired as one token every `rps` seconds, so after the burst drained, sustained traffic was far below the configured RPS (e.g. ~1 req/min at 60 RPS). > > **`apply_rate_limit_layer`** now sets **`.period(replenish_period_for_rps(rps))`** with `1s / rps` instead of **`.per_second(rps)`**, so global and LCD-heavy governors actually replenish at the intended requests-per-second. Burst size is unchanged (`2 × rps`). > > Adds unit tests for the period math and an integration test that drains burst at 5 RPS, waits ~1.1s, and expects ~5 successes again. Docs note replenish = `1s / RPS`, and that **dev** must set **`RATE_LIMIT_RPS=0` and `RATE_LIMIT_LCD_HEAVY_RPS=0`** to disable all governors. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit bdfeeef671cdfee58dbb21b59825995005b1b7b5. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
ghost1 commented 2026-06-10 03:33:22 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-10 03:33:29 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-10 05:31:28 +00:00 (Migrated from gitlab.com)

mentioned in commit 0ee39be2a8

mentioned in commit 0ee39be2a83a5cfc76596aa4de3ce160f1650a70
PlasticDigits (Migrated from gitlab.com) merged commit 0ee39be2a8 into main 2026-06-10 05:31:28 +00:00
Brouie commented 2026-06-10 06:29:46 +00:00 (Migrated from gitlab.com)

mentioned in issue #355

mentioned in issue #355
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic!852
No description provided.