Artículos sobre: Aplicaciones & Bots

Cómo lidiar con los ratelimits de la API de Discord

Cómo lidiar con los ratelimits de la API de Discord: la guía definitiva


Si desarrollas bots para Discord, tarde o temprano tu aplicación recibirá un código de estado HTTP 429 (Too Many Requests). Discord impone reglas estrictas de tráfico para proteger su infraestructura contra abusos y ataques de denegación de servicio.


Para que tu bot opere con la máxima estabilidad, necesitas entender la mecánica interna de esos límites y blindar tu código con un sistema de colas y caché.


1. Anatomía de los ratelimits de Discord


Discord divide sus restricciones en capas bien definidas. Los límites se cuentan en base al token de tu bot y a la IP desde donde parten las peticiones.


El límite global (Global Rate Limit)

Por defecto, Discord aplica un límite global de 50 peticiones por segundo para cada token de bot. Si tu bot intenta disparar 51 peticiones en un único segundo (aunque sean para endpoints totalmente diferentes), la API lo bloqueará temporalmente.


Límites por ruta y buckets (Per-Route Limits)

Además del límite global, cada ruta de la API posee su propio "bucket" (cubo) de créditos, generalmente atado a un identificador principal (como el ID de un servidor o de un canal).

  • Rutas comunes: Enviar mensajes en un canal específico tiene un límite diferente al de editar el apodo de un usuario.
  • La ruta crítica de creación/edición de canales: Modificar o crear canales en un servidor es una de las operaciones más monitoreadas por Discord para evitar ataques de raid. Las modificaciones del nombre o el tema de un canal, por ejemplo, están estrictamente limitadas a 2 cambios cada 10 minutos por canal. Abusar de esa ruta genera bloqueos severos al instante.


Las cabeceras HTTP de control

Siempre que tu bot hace una petición REST, Discord responde con cabeceras que revelan la salud de tu bucket actual. Tu código debe leer y respetar esos datos:


* X-RateLimit-Limit: El número máximo de peticiones que puedes hacer.
* X-RateLimit-Remaining: Cuántas peticiones te quedan en el bucket actual.
* X-RateLimit-Reset-After: Los segundos que faltan hasta que el bucket se reinicie.
* X-RateLimit-Bucket: La string identificadora única de ese bucket específico.


2. La solución arquitectónica: sistema de colas


La forma más eficiente de evitar alcanzar el límite de Discord es implementar un sistema de colas asíncronas. En vez de permitir que tus comandos ejecuten peticiones REST directamente a la API de Discord a medida que ocurren las interacciones, lanzas esas acciones a una cola controlada por un trabajador (worker).


El worker consume la cola secuencialmente o por lotes, verificando las cabeceras de ratelimit antes de realizar el siguiente disparo. Si el indicador X-RateLimit-Remaining llega a cero, la cola se congela voluntariamente durante los segundos informados en X-RateLimit-Reset-After.


Ejemplo conceptual de cola optimizada (Python / Asyncio)


Aquí tienes un ejemplo básico de cómo estructurar un despachador de peticiones que respeta los tiempos de espera impuestos por la API:


import asyncio
import time

class DiscordRequestQueue:
def __init__(self):
self.queue = asyncio.Queue()
self.is_frozen = False
self.resume_time = 0

async def add_request(self, action_coroutine):
"""Adiciona uma ação de API à fila"""
await self.queue.put(action_coroutine)

async def start_worker(self):
"""Worker que processa e monitora os limites continuamente"""
while True:
# Se a fila estiver congelada por ratelimit, aguarda o reset
if self.is_frozen:
now = time.time()
if now < self.resume_time:
await asyncio.sleep(self.resume_time - now)
self.is_frozen = False

# Pega a próxima requisição da fila
action = await self.queue.get()

try:
# Executa a chamada HTTP para o Discord
response = await action()

# Simulação da leitura dos cabeçalhos do Discord
remaining = int(response.headers.get("X-RateLimit-Remaining", 1))
reset_after = float(response.headers.get("X-RateLimit-Reset-After", 0))

if remaining == 0:
# Congela o processador baseado na resposta do Discord
self.is_frozen = True
self.resume_time = time.time() + reset_after

except Exception as e:
# Trata erros 429 inesperados com Recuo Exponencial (Backoff)
print(f"Erro na requisição: {e}")

finally:
self.queue.task_done()


3. Otras buenas prácticas cruciales


Además de gestionar tus peticiones REST con colas, adopta los siguientes hábitos de desarrollo para reducir la carga contra la API:


1. Caché agresivo de datos

Nunca consultes la API de Discord para obtener información estática o que cambia poco.

  • Datos de servidores: Mantén los nombres de los canales, roles y permisos guardados en la memoria local de tu bot (o en una instancia externa de Redis).
  • Biblioteca nativa: Si usas wrappers modernos como discord.py o discord.js, ya cuentan con sistemas de caché interno automáticos. Evita esquivarlos usando métodos como fetch_channel() (que hace una llamada REST directa) cuando puedas usar get_channel() (que busca en el caché local).


2. Da preferencia al Gateway y a los Webhooks

  • Gateway (WebSockets): Usa eventos del Gateway para recibir actualizaciones en tiempo real en vez de hacer "polling" (preguntar constantemente a la API si algo cambió).
  • Webhooks para envío masivo: Si tu bot necesita disparar logs de acciones, anuncios masivos o feeds de noticias en canales, utiliza Webhooks. Los Webhooks tienen límites de peticiones aislados de tu aplicación principal (generalmente 30 peticiones cada 5 segundos por webhook), ahorrando el límite global de 50/s del token de tu bot.


3. Implementa Exponential Backoff (recuo exponencial)

Si por algún desajuste de concurrencia bombardeas la API inmediatamente después de recibir un 429, Discord extenderá el castigo o baneará temporalmente la IP de tu VPS/alojamiento por comportamiento abusivo.

Actualizado el: 13/06/2026

¿Este artículo te resultó útil?

Comparte tu opinión

Cancelar

¡Gracias!