Rate Limiter Middleware

mediumTypeScript

Lesson

Rate Limiting with Sliding Windows

Rate limiting is a crucial technique for protecting APIs from abuse and ensuring fair resource usage. It controls how many requests a client can make within a specific time period. There are several approaches to rate limiting, but one of the most effective is the sliding window algorithm.

Why Rate Limiting Matters

Without rate limiting, a single client could overwhelm your server with requests, causing performance issues for other users. Rate limiting helps maintain service quality, prevents abuse, and can protect against certain types of attacks like DDoS.

Fixed Window vs Sliding Window

A fixed window approach divides time into discrete chunks (like every minute from 0-60 seconds) and resets the counter at each boundary. This can lead to "burst" problems where a client makes many requests at the end of one window and the beginning of the next.

A sliding window approach is more sophisticated. Instead of fixed time boundaries, it looks back at the last N seconds from the current moment. This provides smoother rate limiting and prevents burst issues.

Implementation Strategy

The key insight is to store timestamps of requests for each client (usually identified by IP address). When a new request comes in, you:

  1. Remove old timestamps that fall outside your time window
  2. Check if the remaining count is under your limit
  3. If allowed, add the current timestamp to the list

This approach requires careful memory management since you're storing data for each client. You'll want to periodically clean up old entries to prevent memory leaks.

Example
1class SimpleRateLimiter { 2 private requests = new Map<string, number[]>(); 3 4 isAllowed(clientId: string, maxRequests: number, windowMs: number): boolean { 5 const now = Date.now(); 6 const clientRequests = this.requests.get(clientId) || []; 7 8 // Remove timestamps older than the window 9 const validRequests = clientRequests.filter(timestamp => 10 now - timestamp < windowMs 11 ); 12 13 // Check if under limit 14 if (validRequests.length < maxRequests) { 15 validRequests.push(now); 16 this.requests.set(clientId, validRequests); 17 return true; 18 } 19 20 return false; 21 } 22}
L6Filter removes old requests outside the sliding window
L11Only add current timestamp if request is allowed
L12Update the stored timestamps with the filtered list plus new request

Key Takeaways

  • •Sliding window rate limiting provides smoother request distribution than fixed windows
  • •Store request timestamps per client and filter out old ones before checking limits
  • •Memory management is crucial - clean up old client data to prevent leaks
Loading...