BullMQ vs Redis Streams: quando usar cada um em automações Node (e onde dá ruim)
- BullMQ é uma biblioteca de fila (opinião: mais rápida para colocar em produção em times Node).
- Redis Streams é um recurso do Redis (opinião: mais flexível, mas você monta mais “peças” em volta).
- Nos dois casos: sem idempotência, a chance de duplicidade em falhas é real.
- A maior diferença prática costuma ser: ergonomia operacional (BullMQ) vs controle e replay (Streams).
O que cada um é (sem marketing)
BullMQ é uma fila de jobs para Node.js construída sobre Redis. Você programa no modelo “job entra → worker processa → sucesso/falha → retry/DLQ”, e a biblioteca já traz muita mecânica pronta: atrasos, repetição, prioridade, concorrência e eventos.
Redis Streams é uma estrutura de dados do Redis para eventos em formato de stream. Ele brilha quando você quer produzir eventos e consumi-los com consumer groups, mantendo histórico e permitindo reprocesso (replay). Só que “fila com retry e DLQ” não cai do céu: você desenha esses fluxos.
Comparativo prático: escolha pelo formato do problema
A pergunta que resolve 80%: você está construindo um sistema de jobs (tarefas) ou um sistema de eventos (log) com possibilidade de reprocessamento e múltiplas leituras?
Em automações (integrações, ETL leve, webhooks, robôs internos), o problema geralmente é job: “pegar item, chamar API, transformar, gravar, notificar”. Aí BullMQ costuma encaixar melhor. Já Streams vira favorito quando você quer reter e reprocessar eventos, ou quando vários serviços/consumidores precisam ler o mesmo fluxo com independência.
| Critério | BullMQ (fila de jobs) | Redis Streams (stream de eventos) |
|---|---|---|
| Modelo mental | Tarefa (job) com ciclo de vida e estado | Log/stream com entradas e consumo por grupos |
| Retry/backoff | Nativo (configuração por job/worker) | Você implementa (ou cria convenções) em cima do stream |
| DLQ (dead-letter) | Comum no ecossistema; fácil de modelar | Precisa desenhar: stream de erro, contadores, expiração, etc. |
| Replay/reprocesso | Possível, mas menos natural (depende de como você guarda payload/ids) | Natural: histórico no stream e controle de offsets/pendências |
| Múltiplos consumidores lendo o mesmo evento | Dá para fazer, mas não é o foco | Ponto forte (consumer groups e múltiplas leituras) |
| Agendamento (delay/cron-like) | Forte (delayed jobs, repeatables) | Você constrói (scheduler externo ou lógica própria) |
| Curva operacional | Geralmente menor para times Node | Maior: demanda disciplina de design e operação |
Onde costuma dar ruim (e como antecipar)
1) Duplicidade silenciosa: quedas, timeouts e retries fazem o mesmo item ser processado duas vezes. Sem idempotência (por exemplo, idempotency key por pedido/lead), você cria efeito cascata: cobrança duplicada, mensagens repetidas, atualizações fora de ordem.
2) “Poison message”: um payload específico sempre falha (por bug ou dado inválido). Em BullMQ você tende a resolver com limite de tentativas e DLQ. Em Streams, se você não tratar pendências e redirecionar para um fluxo de erro, o grupo pode ficar travado em itens impossíveis.
3) Falta de visibilidade: fila/stream sem métrica vira caixa-preta. Em BullMQ é comum instrumentar por estado do job. Em Streams você precisa observar lag (atraso), tamanho do stream, pendências por consumer e taxa de reentrega.
- Regra de ouro: retries sem idempotência são duplicidade programada.
- Defina desde o início: limite de tentativas, janela de reprocesso e estratégia de DLQ.
- Se o trabalho chama APIs externas, trate 429/5xx com backoff e jitter, não com retry agressivo.
Guia rápido de decisão (3 perguntas)
Use como checklist antes de escolher (ou antes de misturar os dois):
- Você precisa reprocessar histórico (replay) com frequência e controle fino? Se sim, Streams tende a ganhar.
- Seu time quer produtividade e um padrão pronto de job/retry/concurrency no Node? BullMQ tende a ganhar.
- Você terá múltiplos consumidores independentes lendo o mesmo fluxo de eventos? Streams tende a ganhar.
Opinião editorial: o que mais vejo funcionar em automação
Para automações internas e integrações de negócio (webhooks, sincronização de CRM/ERP, enriquecimento de leads), BullMQ costuma acelerar o “time-to-production” porque já empacota muita disciplina operacional.
Redis Streams aparece mais quando o problema já nasceu orientado a eventos: você quer registrar tudo que acontece e permitir reprocesso, auditoria, múltiplas leituras e consumidores diferentes. Aí vale pagar a complexidade — desde que a equipe abrace padrões (DLQ, idempotência, monitoramento) desde o primeiro dia.
Perguntas frequentes
BullMQ substitui Redis Streams?
Dá para ter DLQ no Redis Streams?
Qual é melhor para garantir ordem de processamento?
Em automações com webhooks, o que escolher?
Leia também
BullMQ vs RabbitMQ: qual fila escolher para automações (especialmente em Node.js e n8n)
Comparativo direto entre BullMQ (Redis) e RabbitMQ para filas em automações: retry, DLQ, ordenação, escalabilidade, operação e encaixe com n8n/Node no Brasil.
Ler →
RabbitMQ vs SQS vs Redis Streams: qual fila escolher para automações (n8n, Make e integrações)
Comparativo prático entre RabbitMQ, Amazon SQS e Redis Streams para filas, retry e desacoplamento de automações. Veja prós, limites típicos e cenários reais (webhooks, picos, DLQ).
Ler →
Exactly-once vs at-least-once em automações: o que muda na prática (e como evitar duplicidade)
Entenda exactly-once, at-least-once e at-most-once em automações (n8n, Make, filas e webhooks). Veja riscos de duplicidade, quando acontece e padrões práticos para reduzir erros.
Ler →
Como usar Dead Letter Queue (DLQ) em automações: trate falhas sem perder eventos
Guia prático de Dead Letter Queue (DLQ) para automações: quando usar, como modelar eventos, reprocessar com segurança e evitar duplicidade em n8n/Make/Zapier.
Ler →