A rate limiter can work perfectly in development and still fail in production.
You test it locally, send too many requests, and receive a 429 Too Many Requests response. Everything looks fine.
Then you deploy your Node.js application with two instances behind a load balancer.
Suddenly, users can send more requests than your limit allows.
The problem isn't necessarily your rate-limiting algorithm. It's where you're storing the request counts.
The Problem With In-Memory Rate Limiting
Consider this Express middleware:
const requests = new Map ();
function rateLimiter ( req , res , next ) { const key = req . ip ; const now = Date . now (); const windowMs = 60 _000 ; const limit = 10 ;
let record = requests . get ( key );
if ( ! record || now - record . start >= windowMs ) { record = { count : 0 , start : now , }; }
record . count ++ ; requests . set ( key , record );
if ( record . count > limit ) { return res . status ( 429 ).…