import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL);
export async function rateLimiter(req, res, next) {
const ip = req.ip;
const key = `rate:${ip}`;
const limit = 100; // max request-uri
const windowSize = 60; // secunde
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, windowSize);
}
if (current > limit) {
return res.status(429).json({ error: 'Prea multe cereri. Ia o pauză.' });
}
next();
}Am trecut prin toate fazele cu rate limiting-ul, de la scripturi Node.js care crăpau memoria RAM până la clustere Redis destul de scumpe. Alegerea tool-ului corect îți salvează nopțile și, mai ales, bugetul de cloud. Hai să facem ordine între Nginx, Redis-ul clasic și variantele serverless ca Upstash ca să nu tragi cu tunul în vrăbii.
Nginx: Scutul de la intrare (Ieftin și brutal)
Pe la începuturi, la un proiect cu vreo 12.000 de useri unici pe zi, ne-am trezit cu un scraper chinezesc care ne bombarda rutele de căutare. Serverul de Express.js era în genunchi, procesorul la 100%. Salvarea? Trei linii în config-ul de Nginx.
Nginx e genial pentru că blochează request-urile proaste înainte ca ele să ajungă la codul tău Node, Python sau Go. Consumul de resurse e aproape zero. Folosește algoritmul leaky bucket și e perfect pentru protecție brută anti-DDoS sau limitat accesul pe rute sensibile (cum e /api/login sau /api/register).
Dar are un mare minus: e rigid. Dacă vrei să schimbi limita dinamic în funcție de abonamentul userului (ex: Free are 100 req/min, Premium are 5000), Nginx devine un coșmar de configurat. Da, poți folosi module de Lua sau NJS, dar deja complici arhitectura aiurea.
Redis self-hosted: Standardul pentru aplicații mari
Dacă ai o arhitectură cu microservicii sau pur și simplu ai nevoie de rate limiting dinamic bazat pe ID-ul de user din baza de date, Redis e regele. Am folosit setup-ul ăsta la o platformă de e-commerce unde trebuia să fim siguri că checkout-ul nu e blocat de boti.
Faci un middleware în aplicație, citești API key-ul sau JWT-ul, verifici în Redis dacă userul a depășit limita din ultimele 60 de secunde și decizi dacă îi dai 429 Too Many Requests. Am economisit cam 30% din timpul de răspuns al API-ului mutând logica de limitare din PostgreSQL în Redis.
Trade-off-ul? Trebuie să administrezi acel Redis. Dacă clusterul de Redis are latență sau pică, ce faci? Mergi pe fail-open (permiți toate request-urile, riscând overload) sau fail-closed (blochezi tot, clienții fiind furioși)? Ambele variante dor.
Upstash Ratelimit: Serverless fără bătăi de cap
Pentru proiecte mici și medii, sau dacă scrii funcții serverless (Vercel, AWS Lambda), Upstash e o binecuvântare. L-am pus recent pe un tool intern de AI unde nu voiam să ridic un Redis doar pentru asta.
Ei folosesc un protocol HTTP foarte rapid și au o librărie de JS (@upstash/ratelimit) care implementează algoritmi complecși (ca sliding window) în doar câteva rânduri de cod.
Merge brici pentru că nu ai infrastructură de administrat. Partea nasoală? Prețul. Când treci de câteva milioane de request-uri pe lună, costul pe request la Upstash devine mult mai mare decât dacă ai rula un Redis mic pe un VPS de 5 dolari.
Concluzie simplă
Regula mea de deget e destul de clară:
- Pune Nginx la nivel global pentru atacuri brute și rute de login.
- Mergi pe Upstash dacă ești pe Next.js/Vercel și vrei să scrii cod rapid, fără servere de administrat.
- Treci pe Redis dedicat când traficul crește și costul Upstash devine vizibil pe factură.
Voi unde puneți frâna de obicei? Direct în proxy sau lăsați aplicația să decidă prin middleware?