fix(ratelimit): persist rate-limit counters across process restarts #1168 - #1301
Open
Wiseman52 wants to merge 1 commit into
Open
fix(ratelimit): persist rate-limit counters across process restarts #1168#1301Wiseman52 wants to merge 1 commit into
Wiseman52 wants to merge 1 commit into
Conversation
Closes rinafcode#1168 In-memory rate-limit counters reset on every deploy, briefly disabling limits. This change backs the in-memory Map with PostgreSQL so counters survive restarts while keeping the synchronous API for all callers. [MODIFY] src/lib/ratelimit.ts - Import query from db pool and persist every write asynchronously - Load non-expired entries from DB on module startup (non-blocking) - Gracefully fall back to in-memory only if DB is unavailable [ADD] src/lib/db/migrations/006_create_rate_limits_table.sql - rate_limits table with identifier (PK), count, reset_at, timestamps - Index on reset_at for efficient expired-entry cleanup [MODIFY] src/lib/ratelimit.test.ts [MODIFY] src/app/api/tutorials/__tests__/ratelimit.test.ts - Mock @/lib/db/pool to prevent real DB calls during tests 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
|
@Wiseman52 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Contributor
|
Well done on the job done so far! |
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.
Overview
This PR backs the in-memory rate-limit counters with PostgreSQL so they survive process restarts and deploys. Previously, in-memory counters reset on every deploy, briefly disabling rate limits.
Related Issue
Closes #1168
Changes
📦 Database Persistence
[MODIFY]
src/lib/ratelimit.tsqueryfrom the DB pool and persist every rate-limit write asynchronously (fire-and-forget)[ADD]
src/lib/db/migrations/006_create_rate_limits_table.sqlrate_limitstable withidentifier(PK),count,reset_at,created_at,updated_atreset_atfor efficient expired-entry cleanup✅ Tests
[MODIFY]
src/lib/ratelimit.test.ts[MODIFY]
src/app/api/tutorials/__tests__/ratelimit.test.ts@/lib/db/poolto prevent real database calls during testsVerification Results
Typecheck:
✅ No new type errors introduced
Tests:
✅
src/lib/ratelimit.test.ts— 25/25 passed✅
src/app/api/tutorials/__tests__/ratelimit.test.ts— 18/18 passed✅
src/app/api/certificates/__tests__/certificate-security.test.ts— 17/17 passed✅
src/lib/db/__tests__/pool.test.ts— 9/9 passedAcceptance Criteria
ratelimit.ts,db/pool.ts)Design Notes
The in-memory
Mapremains the fast synchronous hot path so that all 30+ existing call sites (withRateLimit, certificate routes, etc.) do not need to become async. Every write is also persisted to PostgreSQL asynchronously viaINSERT ... ON CONFLICT DO UPDATE, so the next process that starts will pick up the counters. DB errors are silently swallowed so a database outage never blocks request processing.🤖 Generated with Codebuff
Co-Authored-By: Codebuff noreply@codebuff.com