eduardweb.
Securitate & AuthIntermediar#performance#nginx#backend#redis#securitate

Rate limiting: Când te salvează Nginx și când ai nevoie de Redis sau Upstash

De Cosmin Rotaru, 22 apr. 2026 · 4 vizualizări · 3 like-uri

Postat acum 5 zile
typescript
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";

// Setup pentru un mediu serverless (Edge)
const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(10, "10 s"),
  analytics: true,
});

export default async function handler(req, res) {
  const identifier = req.ip ?? "127.0.0.1";
  const { success, limit, reset, remaining } = await ratelimit.limit(identifier);

  if (!success) {
    return res.status(429).json({
      error: "Prea multe cereri",
      limit,
      remaining,
      reset
    });
  }

  // Business logic aici...
}

Am văzut de prea multe ori scenariul ăsta: lansezi un API, totul e frumos, până când un client (sau un bot) decide să facă 500 de request-uri pe secundă dintr-o buclă while(true). Dacă nu ai rate limiting, baza de date e prima care crapă sub presiune. M-am lovit de asta la un proiect cu vreo 12k useri activi, unde un singur integrator care și-a configurat prost scriptul de sync ne-a dus CPU-ul în 100% în mai puțin de două minute.

Nu există o soluție universală, dar există un moment potrivit pentru fiecare unealtă. De obicei, alegerea depinde de unde rulezi codul și cât de multă granularitate ai nevoie.

Nginx: Prima linie de apărare

Nginx e sfânt pentru protecție brută. Dacă vrei să oprești atacurile de tip brute force sau pur și simplu să te asiguri că un IP nu îți inundă serverul, limit_req_zone e cel mai ieftin mod. Se întâmplă la nivel de infrastructură, deci request-ul nici nu mai ajunge să consume memorie în aplicația ta Node sau Go.

Trade-off-ul e că e rigid. E greu să faci rate limiting bazat pe un user_id extras dintr-un JWT sau pe un plan tarifar (Free vs Premium). L-am folosit cu succes la un proiect de tip legacy pentru a limita accesul la paginile de login și register. Am economisit cam 20% din resursele serverului doar trântind o regulă de 5 req/sec pe acele rute. Dar dacă ai nevoie de logică de business, Nginx devine rapid un coșmar de configurat.

In-memory: Bun, dar periculos

Mulți încep cu un middleware simplu care ține un obiect în memorie. E super rapid, zero latență de rețea și nu te costă nimic. Totuși, am învățat pe pielea mea că in-memory e o capcană dacă ai mai mult de o instanță de server.

Când ai 3 pod-uri în Kubernetes sau rulezi pe un serviciu de tip Cloud Run, fiecare instanță are propria ei memorie. Dacă pui o limită de 100 de request-uri, un user poate face de fapt 300, fiindcă load balancer-ul îl plimbă de la un pod la altul. E ok pentru aplicații mici, monoliți pe un singur VPS, dar cam atât. Plus că la fiecare restart de server, toți contoarele se resetează.

Redis și Upstash: Standardul de aur

Aici lucrurile devin serioase. Dacă ai o arhitectură distribuită, ai nevoie de un state centralizat. Redis e perfect pentru asta pentru că e incredibil de rapid și are operațiuni atomice. Poți implementa algoritmi ca Sliding Window sau Token Bucket fără să-ți fie frică de race conditions.

Recent am trecut pe Upstash Ratelimit pentru un proiect serverless pe Vercel și mi-a scos fire albe mai puține. Upstash e practic Redis, dar optimizat pentru HTTP și Edge. Într-un setup unde ai funcții Lambda care pornesc și se opresc, nu vrei să menții conexiuni TCP persistente la un Redis clasic.

La proiectul menționat, am redus costurile cu baza de date cu aproape 15% după ce am implementat un rate limit agresiv pe endpoint-urile de search, folosind Upstash. Am putut să setez limite diferite: 10 căutări pe minut pentru useri anonimi și 100 pentru cei logați.

Ce alegi până la urmă?

Regula mea de aur e simplă: folosește Nginx pentru a proteja serverul de atacuri generice și Redis/Upstash pentru a proteja resursele de business (DB, API-uri externe plătite). In-memory e doar pentru prototipuri sau tool-uri interne unde nu contează dacă cineva sare calul.

Trade-off-ul principal la Redis/Upstash este latența adăugată. Chiar dacă e mică (2-10ms), e totuși un network hop în plus. Dacă API-ul tău trebuie să răspundă în sub 50ms constant, s-ar putea să simți diferența.

Voi cum gestionați limitele astea? Preferați să le puneți la intrarea în infrastructură sau cât mai aproape de codul de business?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.