web / lib/services/rate-limit-service
lib/services/rate-limit-service
Provides a service for rate-limiting requests.
This service implements a flexible, in-memory rate-limiting mechanism to protect endpoints from abuse. It tracks requests from different identifiers (like IP addresses or session IDs) and enforces limits based on a specified number of requests within a given time window.
Rate Limiting vs Quotas
This service works alongside QuotaService but serves a different purpose:
RateLimitService (this service):
- Purpose: Short-term abuse prevention (DDoS, spam, burst attacks)
- Storage: In-memory (fast, ephemeral)
- Scope: Per IP address or identifier
- Time windows: Seconds to hours
- Reset: Sliding windows
QuotaService:
- Purpose: Long-term resource management (fair usage, capacity planning)
- Storage: Database (persistent, accurate)
- Scope: Per user ID
- Time windows: Hours to lifetime
- Reset: Fixed times (midnight UTC)
Both checks typically run together - rate limits first (fast fail), then quotas (accurate tracking).
Example
// Typical usage pattern: check both rate limits and quotas
import { getRateLimitService } from '@/lib/services/rate-limit-service';
import { createQuotaService } from '@/lib/services/quota-service';
// 1. Rate limit check (fast, prevents abuse)
const rateLimitService = getRateLimitService(payload);
const rateCheck = rateLimitService.checkTrustLevelRateLimit(
clientIp,
user,
"FILE_UPLOAD"
);
if (!rateCheck.allowed) {
return res.status(429).json({ error: "Too many requests" });
}
// 2. Quota check (accurate, tracks long-term usage)
const quotaService = createQuotaService(payload);
const quotaCheck = await quotaService.checkQuota(
user,
"FILE_UPLOADS_PER_DAY"
);
if (!quotaCheck.allowed) {
throw new QuotaExceededError(...);
}
// 3. Process the request
await processFileUpload();Key features include:
- Multi-window rate limiting (burst, hourly, daily)
- Trust-level-aware rate limits
- Checking if a request is allowed
- Blocking identifiers that exceed the limit
- Providing standard rate-limit headers for HTTP responses
- Automatic cleanup of expired entries
See
- QuotaService for long-term resource management
- Rate Limiting Documentation
- Quotas Documentation
Classes
RateLimitService
Constructors
Constructor
new RateLimitService(
payload):RateLimitService
Parameters
payload
BasePayload
Returns
Methods
destroy()
destroy():
void
Cleanup method to clear interval and cache.
Returns
void
checkRateLimit()
checkRateLimit(
identifier,limit?,windowMs?):object
Check if a request should be rate limited.
Parameters
identifier
string
IP address or session ID.
limit?
number = 10
Maximum requests allowed
windowMs?
number = ...
Time window in milliseconds
Returns
object
Object containing rate limit status
allowed
allowed:
boolean
remaining
remaining:
number
resetTime
resetTime:
number
blocked
blocked:
boolean
checkMultiWindowRateLimit()
checkMultiWindowRateLimit(
baseIdentifier,windows):MultiWindowRateLimitResult
Check multiple rate limit windows for a single identifier.
This method checks all configured windows and returns on the first failure. It’s useful for implementing complex rate limiting strategies like:
- Burst protection (e.g., 1 request per 10 seconds)
- Hourly limits (e.g., 5 requests per hour)
- Daily limits (e.g., 100 requests per day).
Parameters
baseIdentifier
string
Base identifier for the request (e.g., “webhook:token123”).
windows
Array of rate limit windows to check.
readonly RateLimitWindow[] | RateLimitWindow[]
Returns
Result indicating if request is allowed and which window failed (if any).
checkConfiguredRateLimit()
checkConfiguredRateLimit(
baseIdentifier,config):MultiWindowRateLimitResult
Check rate limits using a configuration object.
Parameters
baseIdentifier
string
Base identifier for the request.
config
Rate limit configuration with windows.
Returns
Result indicating if request is allowed.
getRateLimitStatus()
getRateLimitStatus(
identifier):{ count: number; resetTime: number; blocked: boolean; }|null
Get current rate limit status without incrementing.
Parameters
identifier
string
Returns
{ count: number; resetTime: number; blocked: boolean; } | null
resetRateLimit()
resetRateLimit(
identifier):void
Reset rate limit for an identifier.
Parameters
identifier
string
Returns
void
blockIdentifier()
blockIdentifier(
identifier,durationMs?):void
Block an identifier immediately.
Parameters
identifier
string
durationMs?
number = ...
Returns
void
getRateLimitHeaders()
getRateLimitHeaders(
identifier,limit):Record<string,string>
Get rate limit headers for HTTP responses.
Parameters
identifier
string
limit
number
Returns
Record<string, string>
getStatistics()
getStatistics():
object
Get statistics about current rate limits.
Returns
object
totalEntries
totalEntries:
number
blockedEntries
blockedEntries:
number
activeEntries
activeEntries:
number
getRateLimitsByTrustLevel()
getRateLimitsByTrustLevel(
user,endpointType):RateLimitConfig
Get rate limit configuration based on user trust level.
Parameters
user
The user object containing trust level
User | null | undefined
endpointType
The type of endpoint (FILE_UPLOAD, API_GENERAL, etc.)
"FILE_UPLOAD" | "API_GENERAL"
Returns
Rate limit configuration for the user’s trust level
checkTrustLevelRateLimit()
checkTrustLevelRateLimit(
identifier,user,endpointType):MultiWindowRateLimitResult
Check rate limits with trust level awareness.
Parameters
identifier
string
IP address or session ID
user
User object to determine trust level
User | null | undefined
endpointType
The type of endpoint
"FILE_UPLOAD" | "API_GENERAL"
Returns
Multi-window rate limit result
Interfaces
MultiWindowRateLimitResult
Result from checking multiple rate limit windows.
Properties
allowed
allowed:
boolean
Whether the request is allowed (passes all windows)
failedWindow?
optionalfailedWindow:string
Name of the window that failed (if any)
resetTime?
optionalresetTime:number
Time when the failed window resets
remaining?
optionalremaining:number
Remaining requests in the most restrictive window
details?
optionaldetails:object
Details of the check that failed
limit
limit:
number
windowMs
windowMs:
number
remaining
remaining:
number
resetTime
resetTime:
number
Functions
getRateLimitService()
getRateLimitService(
payload):RateLimitService
Parameters
payload
BasePayload
Returns
resetRateLimitService()
resetRateLimitService():
void
Reset the rate limit service singleton (for testing). Call this in afterEach/afterAll to ensure clean state between tests.
Returns
void
getClientIdentifier()
getClientIdentifier(
request):string
Parameters
request
Request
Returns
string
References
RATE_LIMITS
Re-exports RATE_LIMITS
RateLimitConfig
Re-exports RateLimitConfig
RateLimitName
Re-exports RateLimitName
RateLimitWindow
Re-exports RateLimitWindow