Rate Limiting en PHP: cómo proteger tu API de sobrecargas y bots

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 PHP: Domina el flujo de peticiones

\n\n

Imagina esto: lanzas una API increíble para tu servicio. Todo funciona perfectamente hasta que un cliente «descontrolado» empieza a golpear tu servidor con miles de peticiones por segundo. O, peor aún, un bot parser decide extraer toda tu base de datos. ¿Te suena? Si no, has tenido suerte. Pero más vale prevenir. Aquí es donde entran en escena el rate limiting y el throttling, dos caballeros que protegerán tu backend de sobrecargas.

\n\n

En este artículo, veremos cómo implementar el límite de peticiones en PHP, analizaremos ejemplos de código reales y entenderemos qué método elegir para tu proyecto. Spoiler: no tendrás que reinventar la rueda, pero conocer los algoritmos básicos es clave.

\n\n

Rate Limiting vs Throttling: ¿cuál es la diferencia?

\n\n

A menudo se usan como sinónimos, pero hay una línea sutil entre ellos.

\n\n
    \n
  • Rate Limiting — es un límite estricto. Dices: «Máximo 100 peticiones por minuto». Cuando se agota el límite, el cliente recibe un HTTP 429 Too Many Requests y se toma un descanso.
  • \n
  • Throttling — es un control más suave. En lugar de bloquear, simplemente ralentizas el procesamiento de las peticiones que exceden el límite, las pones en cola o reduces su prioridad.
  • \n
\n\n

En la práctica, el throttling en PHP a menudo se implementa con retardos (sleep) o colas, mientras que el rate limiting se basa en contar peticiones por unidad de tiempo. Para la mayoría de las puertas de enlace de API, lo óptimo es una combinación de ambos enfoques.

\n\n

¿Por qué es crítico para tu proyecto?

\n\n

Hay al menos tres razones para implementar el límite de peticiones en PHP:

\n\n
    \n
  • Protección contra DDoS y bots — incluso un script simple puede tumbar tu servidor si no controlas la frecuencia de las llamadas.
  • \n
  • Distribución justa de recursos — un cliente «codicioso» no debe privar del servicio al resto de usuarios.
  • \n
  • Estabilidad y previsibilidad — sabes qué pico de carga esperar y puedes configurar tu infraestructura correctamente.
  • \n
\n\n

Algoritmos de Rate Limiting: elige tu estrategia

\n\n

Antes de escribir código, analicemos tres algoritmos populares. Cada uno tiene sus pros y sus contras.

\n\n

1. Fixed Window (Ventana fija)

\n

El enfoque más simple. Dividimos el tiempo en segmentos (por ejemplo, por minutos). Registramos cuántas peticiones llegan en la ventana actual. Si se alcanza el límite, bloqueamos hasta la siguiente ventana.

\n\n

Inconveniente: en los bordes de las ventanas puede haber un pico: el cliente puede enviar 100 peticiones al final de un minuto y otras 100 al inicio del siguiente, lo que da 200 en 2 segundos.

\n\n

2. Sliding Window (Ventana deslizante)

\n

Un algoritmo más preciso. En lugar de segmentos fijos, miramos los últimos N segundos. Las peticiones «envejecen» y salen de la ventana. Esto elimina los picos en los límites.

\n\n

3. Token Bucket (Cubo de tokens)

\n

Un algoritmo elegante del mundo de las redes. En un «cubo» hay tokens. Cada petición toma un token. Los tokens se reponen a una velocidad determinada. Si el cubo está vacío, la petición se rechaza. Ideal para throttling en PHP, ya que permite pequeños picos de tráfico.

\n\n

Implementación práctica: de lo simple a lo complejo

\n\n

Pasemos al código. Empezaremos con un ejemplo básico usando archivos y luego veremos soluciones listas para producción.

\n\n

Rate Limiter básico con archivos (para aprender)

\n\n

Este ejemplo usa archivos para almacenar contadores. No es apto para producción, pero demuestra perfectamente el principio.

\n\n
<?php\nclass SimpleRateLimiter {\n    private string $storageDir;\n    private int $maxRequests;\n    private int $windowSeconds;\n\n    public function __construct(string $storageDir, int $maxRequests = 100, int $windowSeconds = 60) {\n        $this->storageDir = rtrim($storageDir, '/') . '/';\n        $this->maxRequests = $maxRequests;\n        $this->windowSeconds =                

Blogs

Book Recommendations