Skip to content

Commit aecbcd5

Browse files
committed
refactor(rateLimit): replace raw Map with TTLCache to remove manual cleanup logic
1 parent de76998 commit aecbcd5

1 file changed

Lines changed: 7 additions & 29 deletions

File tree

lib/rate-limit.ts

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,8 @@ interface RateLimitResult {
4545
reset: number;
4646
}
4747

48-
const trackers = new Map<string, { count: number; expires: number }>();
48+
const trackers = new TTLCache<{ count: number }>(2000, 60000);
4949

50-
/**
51-
* Checks if a request from a given IP should be rate limited.
52-
*
53-
* @param ip The IP address to track
54-
* @param limit Maximum number of requests allowed in the window
55-
* @param windowMs Time window in milliseconds
56-
* @returns RateLimitResult
57-
*/
5850
export function rateLimit(
5951
ip: string,
6052
limit: number = 60,
@@ -63,46 +55,32 @@ export function rateLimit(
6355
const now = Date.now();
6456
const tracker = trackers.get(ip);
6557

66-
// Periodic cleanup of the map to prevent memory leaks.
67-
// We perform a partial cleanup if the map grows too large.
68-
if (trackers.size > 2000) {
69-
let cleaned = 0;
70-
for (const [key, value] of trackers.entries()) {
71-
if (now > value.expires) {
72-
trackers.delete(key);
73-
cleaned++;
74-
}
75-
// Stop cleaning after some work to avoid blocking the request for too long
76-
if (cleaned > 500) break;
77-
}
78-
}
79-
80-
if (!tracker || now > tracker.expires) {
81-
const expires = now + windowMs;
82-
trackers.set(ip, { count: 1, expires });
58+
if (!tracker) {
59+
trackers.set(ip, { count: 1 }, windowMs);
8360
return {
8461
success: true,
8562
limit,
8663
remaining: limit - 1,
87-
reset: expires,
64+
reset: now + windowMs,
8865
};
8966
}
9067

9168
tracker.count++;
69+
trackers.set(ip, tracker, windowMs);
9270

9371
if (tracker.count > limit) {
9472
return {
9573
success: false,
9674
limit,
9775
remaining: 0,
98-
reset: tracker.expires,
76+
reset: now + windowMs,
9977
};
10078
}
10179

10280
return {
10381
success: true,
10482
limit,
10583
remaining: limit - tracker.count,
106-
reset: tracker.expires,
84+
reset: now + windowMs,
10785
};
10886
}

0 commit comments

Comments
 (0)