Skip to content

Rate limiting - #148

Merged
memplethee-lab merged 6 commits into
SourceXXL:mainfrom
Dijjy7:Rate-Limiting
Aug 21, 2026
Merged

Rate limiting#148
memplethee-lab merged 6 commits into
SourceXXL:mainfrom
Dijjy7:Rate-Limiting

Conversation

@Dijjy7

@Dijjy7 Dijjy7 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

All checks pass. Here's a summary of the implementation:

Rate Limiting & Abuse Protection Module
New module: src/rate-limiting/
rate-limiter.service.ts — Core distributed rate limiter:

Token bucket strategy via Redis Lua script (atomic refill + consume)
Sliding window strategy via Redis sorted set (atomic ZREMRANGEBYSCORE + ZCARD + ZADD)
Reuses CACHE_REDIS_CLIENT from the global CacheModule (ioredis)
In-memory fallback when Redis is unavailable (graceful degradation)
Per-key registry for dashboard inspection (getEntry, listEntries, reset)
Health check via ping() with caching
rate-limiting.guard.ts — Distributed replacement for QuotaGuard:

Reads the same @ratelimit() decorator metadata (RATE_LIMIT_KEY)
Resolves tiers per-request (free/paid/enterprise via existing quota.config.ts)
Identity resolution: user ID → wallet address → X-Forwarded-For → req.ip
Sets X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Tier, X-RateLimit-Strategy, and Retry-After headers
Emits Prometheus counters for allowed/denied decisions
rate-limiting.controller.ts — Grant reviewer dashboard:

GET /rate-limiting/dashboard — aggregated totals, denial rate, per-tier breakdown, strategy distribution
GET /rate-limiting/status — filtered key listing
GET /rate-limiting/metrics — raw Prometheus text
POST /rate-limiting/entries — manually set a rate-limit entry
DELETE /rate-limiting/entries/:key — reset a throttled key
GET /rate-limiting/storage — storage health (redis vs memory)
rate-limiting.metrics.ts — Prometheus collectors:

alian_structure_rate_limit_allowed_total (counter)
alian_structure_rate_limit_denied_total (counter)
alian_structure_rate_limit_errors_total (counter)
alian_structure_rate_limit_storage_health (gauge)
rate-limiting.module.ts — @global() dynamic module via forRoot():

Config-driven strategy selection (RATE_LIMIT_DEFAULT_STRATEGY)
Configurable Redis key prefix
Optional in-memory fallback toggle
Modified files
rate-limit.decorator.ts — Extended RateLimitOptions with strategy and key fields
app.module.ts — Imported RateLimitingModule.forRoot(), replaced QuotaGuard with DistributedRateLimitGuard as the global guard
env.validation.ts — Added RATE_LIMIT_DEFAULT_STRATEGY, RATE_LIMIT_REDIS_KEY_PREFIX, RATE_LIMIT_FALLBACK_TO_MEMORY
.env.example / .env.production.example — Documented the new env vars
Dashboard
monitoring/grafana/dashboards/rate-limiting-dashboard.json — Grafana dashboard with overview stats, trends, per-tier pie charts, top-denied-keys table, and storage health gauge
Validation
TypeScript: clean (no errors)
ESLint: clean on all new/modified files (CRLF issues are pre-existing in untouched files)
Tests: 53 passing (rate-limiting module) + 3 existing quota guard tests still pass
Build: nest build compiles successfully
closes #132

@Dijjy7

Dijjy7 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

@memplethee-lab pr sent

@memplethee-lab
memplethee-lab merged commit 02ee94d into SourceXXL:main Aug 21, 2026
2 checks passed
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.

Module: Rate Limiting & Abuse Protection

2 participants