Limitación de solicitudes en JavaScript: cómo evitar que la API se caiga

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Rate limiting y throttling en JavaScript: Protección y rendimiento

\n\n

¿Alguna vez se ha preguntado por qué después de un par de docenas de clics rápidos en el botón «Enviar», su servicio favorito deja de responder? ¿O por qué algunos sitios web le piden que «espere 30 segundos» antes de reenviar un formulario? La respuesta está en dos potentes mecanismos que salvan el backend de la sobrecarga y a los usuarios de los «errores»: rate limiting y throttling.

\n\n

En este artículo, analizaremos cómo aplicar estas técnicas en JavaScript puro y Node.js. Aprenderá en qué se diferencia throttle de debounce, cómo escribir un rate limiter simple para una API y por qué su sitio web funcionará más rápido. ¡Vamos allá!

\n\n

¿Qué es rate limiting y por qué es necesario?

\n\n

Rate limiting (limitación de velocidad de solicitudes) es un mecanismo de protección que limita la cantidad de solicitudes de un cliente (o dirección IP) en un período de tiempo determinado. Imagínese una barrera: un coche puede pasar, pero solo una vez cada 10 segundos.

\n\n

¿Dónde se aplica?

\n
    \n
  • Protección de API contra ataques DDoS y spam.
  • \n
  • Prevención de sobrecarga del servidor ante solicitudes masivas.
  • \n
  • Control del uso de recursos en API de pago (por ejemplo, 100 solicitudes por hora).
  • \n
  • Protección contra errores de «bucle infinito» en el cliente.
  • \n
\n\n

A diferencia del throttling, que suaviza el flujo de solicitudes, rate limiting es un muro rígido: «Alto, has superado el límite».

\n\n

Throttling vs Debounce: la principal diferencia

\n\n

A menudo se confunden throttling y debounce. Aclaremos los conceptos.

\n\n
    \n
  • Throttle — garantiza que una función no se llame más de una vez cada N milisegundos. Imagine un grifo de agua: lo abre y el agua fluye a una velocidad constante, incluso si mueve la manija más rápido.
  • \n
  • Debounce — pospone la llamada a una función hasta que hayan pasado N milisegundos desde el último evento. Ideal para la búsqueda con autocompletado: mientras el usuario escribe, no se envía la solicitud.
  • \n
\n\n

En el contexto de rate limiting, nos interesa específicamente throttle: queremos controlar la frecuencia, no posponer las solicitudes.

\n\n

Rate limiter simple en JavaScript

\n\n

Escribamos nuestra propia implementación de rate limiter en Node.js. Recordará la hora de la última solicitud de cada usuario y bloqueará las solicitudes demasiado frecuentes.

\n\n
class RateLimiter {\n  constructor(limit, windowMs) {\n    this.limit = limit;          // Máximo de solicitudes\n    this.windowMs = windowMs;    // Ventana de tiempo en ms\n    this.requests = new Map();   // Almacenamiento: userId -> [timestamps]\n  }\n\n  allow(userId) {\n    const now = Date.now();\n    const userRequests = this.requests.get(userId) || [];\n    \n    // Eliminar registros antiguos\n    const recentRequests = userRequests.filter(\n      ts => now - ts < this.windowMs\n    );\n    \n    if (recentRequests.length >= this.limit) {\n      console.log(`Límite de velocidad excedido para ${userId}`);\n      return false;\n    }\n    \n    recentRequests.push(now);\n    this.requests.set(userId, recentRequests);\n    return true;\n  }\n}\n\n// Uso\nconst limiter = new RateLimiter(5, 60000); // 5 solicitudes por minuto\n\n// Simulación de solicitudes\nfor (let i = 0; i < 10; i++) {\n  setTimeout(() => {\n    const allowed = limiter.allow('user123');\n    console.log(`Solicitud ${i+1}: ${allowed ? '✅ Permitida' : '❌ Bloqueada'}`);\n  }, i * 2000); // Cada 2 segundos\n}
\n\n

Este código es excelente para fines educativos, pero en producción es mejor usar soluciones ya preparadas (por ejemplo, express-rate-limit para Express o rate-limiter-flexible).

\n\n

Throttling en el cliente: protección contra clics rápidos

\n\n

A menudo, el problema surge en el lado del cliente: el usuario hace clic varias veces en el botón «Enviar» y las solicitudes se envían en paralelo. R

Blogs

Book Recommendations