Saltar al contenido principal
WhatsApp banea cuentas que envían demasiados mensajes en poco tiempo. El rate limiter integrado del provider Baileys protege tu bot automáticamente — está activo por defecto y se sitúa dentro del pipeline de envío saliente del provider, así que cada ctx.reply(), bot.send(), bot.broadcast() y envío de media pasa por él.
Pacing propio de cada transporteEn v2 la política de pacing vive en el provider, no en el core: cada transporte puede aplicar sus propios límites (429s de Telegram, buckets de Discord, tiers de la Cloud API — expuestos como RateLimitedError tipados). Esta página cubre el limiter de token bucket de WhatsApp (Baileys) que configuras al construir BaileysProvider.

Cómo funciona

El limiter usa un algoritmo de token bucket con dos buckets independientes:
  • Por chat — limita qué tan rápido puedes enviar a una sola conversación.
  • Global — limita tu throughput saliente total entre todos los chats.
Cuando un bucket se vacía, los mensajes se encolan (no se descartan) y se liberan conforme los tokens se recargan; un chat frenado no retiene a los demás. Un envío que espera en la cola más de maxWait (30 s por defecto) rechaza con RateLimiterTimeout, un RateLimitedError, así que quien envía nunca se queda colgado. Un jitter opcional agrega un delay aleatorio tipo humano entre envíos.

Configuración

Pasa rateLimit al constructor del provider (BotConfig.rateLimit está obsoleta: el core la ignora y avisa en el log):

Desactivar el rate limiting

Para tests o entornos de alta confianza:

Configuraciones recomendadas

Las cuentas nuevas son más sensiblesUn número de WhatsApp recién registrado se banea más rápido que uno con antigüedad. Empieza conservador (3 / 10s por chat, 20 / 60s global) y aumenta gradualmente.

Acceso programático

La instancia de RateLimiter es interna, pero puedes importar la clase desde el paquete de transporte para uso avanzado:

Límites cortos en los envíos de ctx

Sea cual sea el transporte, un envío de ctx (reply, say, media, en handlers, flujos y conversaciones) que el provider rechaza con un RateLimitedError que pide una espera corta se reintenta en el sitio, para que un paso de conversación no termine por un 429 pasajero: por defecto una vez, cuando retryAfterMs es de 5 s como mucho. BotConfig.rateLimitRetry lo ajusta (retries cuenta los intentos después del primero):
Una espera más larga, otros errores y bot.send() fallan como antes; bot.broadcast() (su opción retries) y el outbox durable tienen su propio back-off.

Interacción con hooks before('send')

El rate limiter corre después de los hooks before('send') pero antes del envío real al provider. Si un hook aborta el envío, el rate limiter nunca se consulta — los envíos abortados no consumen tokens.