1) Identifique o tipo de duplicação (antes de mexer no fluxo)
Primeiro descubra “de onde” a duplicação nasce: (a) o provedor manda o mesmo webhook mais de uma vez, (b) seu n8n reprocessa por erro/timeout, (c) o usuário clica duas vezes (ou o front dispara duplicado), (d) há dois gatilhos para o mesmo evento (ex.: webhook + polling) ou (e) seu fluxo tem um loop/ramo paralelo que envia duas vezes.
2) Crie uma chave de idempotência por mensagem/evento
Defina uma chave única que represente “este evento que gera esta mensagem”. Exemplos: message_id do provedor + número + template + data; ou order_id + etapa + destinatário. Essa chave é o seu ‘CPF do envio’. Tudo que vier repetido com a mesma chave deve ser ignorado.
3) Registre e bloqueie duplicatas (dedupe) em um lugar confiável
Guarde a chave de idempotência num storage com escrita atômica (banco, Redis, Postgres, etc.). Ao receber o evento: tente criar o registro; se já existir, pare o fluxo sem enviar. Se você não tem banco, dá para começar com uma planilha/Google Sheets, mas o risco de condição de corrida é maior quando há volume.
4) Separe ‘receber evento’ de ‘enviar mensagem’ com fila (quando houver volume)
O padrão robusto é: webhook → validação → dedupe → enfileirar job → worker envia. Isso reduz duplicação por timeout e facilita retry controlado. Se não tiver fila, simule com uma tabela de “pendências” e um workflow cron que processa com lock.
5) Configure retry com backoff e limite — e trate timeout como ‘incerto’
Quando o envio falhar, não tente imediatamente em loop apertado. Use backoff (espera crescente) e um limite de tentativas. Se você não recebeu confirmação do envio (timeout), trate como estado incerto: consulte status (se a API permitir) ou use dedupe por chave antes de reenviar.
6) Garanta que o webhook responda rápido (ack) e processe depois
Muita duplicação vem de reentregas do provedor porque seu endpoint demorou para responder. Responda 200 o mais rápido possível após validar assinatura/formato e gravar o evento. O processamento pesado (IA, consulta a CRM, montagem de mensagem) fica após o ack.
7) Feche as brechas clássicas: dois gatilhos, paralelismo e reexecução manual
Verifique se há dois workflows reagindo ao mesmo evento (ex.: um webhook e um polling). Revise ramos paralelos que convergem para o mesmo nó de envio. E se alguém reexecuta manualmente execuções no n8n, imponha dedupe: reprocessar pode ser legítimo, reenviar mensagem não.
Por que WhatsApp duplica mensagem em automação (mesmo quando “parece certo”)?
WhatsApp (e fornecedores em geral) operam com reentrega: se o endpoint não confirma rápido ou se há falha de rede, o mesmo evento pode chegar de novo. Do lado do n8n, retries e reexecuções também são comuns. Sem idempotência, o sistema faz o que você mandou: executa duas vezes e envia duas vezes.
A mentalidade correta é assumir duplicação como condição normal, não como exceção. A automação precisa ser resistente a eventos repetidos.
Checklist anti-duplicação (o que resolve na prática)
Se você só fizer duas coisas, faça estas: (1) idempotência por chave e (2) ack rápido no webhook. O resto melhora robustez, mas essas duas cortam a maior parte dos casos.
Tabela: causa provável → correção recomendada
Use a tabela como mapa de diagnóstico. Nem sempre dá para saber a origem no primeiro olhar, mas dá para validar rápido pelos timestamps e pelo payload recebido.
| Causa provável | Como confirmar | Correção que costuma funcionar |
|---|---|---|
| Reentrega do webhook (timeout/lentidão) | Mesmo payload chega mais de uma vez com intervalo curto; logs mostram resposta lenta | Ack 200 rápido + registrar evento + processar assíncrono |
| Retry agressivo no n8n | Execuções repetidas com o mesmo input após falha | Backoff + limite de tentativas + dedupe por chave antes de enviar |
| Dois gatilhos para o mesmo evento | Há webhook e polling, ou dois workflows com o mesmo gatilho | Escolher um modelo (webhook ou polling) e consolidar o fluxo |
| Paralelismo/ramo duplicado no workflow | Duas trilhas chegam no nó de envio | Colocar “porta” de dedupe antes do envio; revisar merge/IF/switch |
| Reexecução manual de execuções | Duplicação só quando alguém reprocessa histórico | Deduplicação obrigatória + botão/rota de reenvio explícito (não automático) |
Padrão recomendado no n8n (arquitetura curta e segura)
Um desenho simples que evita 90% das dores é: Webhook (recebe) → validar assinatura/formato → gerar idempotencyKey → storage (insert-if-not-exists) → fila/tabela de jobs → worker de envio → registrar status.
Se você ainda não usa fila, dá para começar com uma tabela de “outbox” (pendências) e um workflow agendado que processa com lock. O essencial é não depender do ‘fluxo rodou uma vez’ como garantia.
Erros que parecem inofensivos, mas duplicam mensagem
Alguns bugs são ‘silenciosos’: um nó de envio duplicado num ramo pouco usado; um merge configurado como “pass-through” e não como espera; ou um nó de erro que, ao falhar, cai numa rota que também envia.
Também é comum o time fazer o webhook esperar uma chamada lenta (IA/CRM). Quando a rede oscila, o provedor reenfileira e você recebe duas vezes. A correção não é “tentar mais rápido”, é responder rápido e processar depois.
Perguntas frequentes
Como criar uma chave de idempotência boa para WhatsApp?
Se eu usar apenas Google Sheets para dedupe, funciona?
Webhooks sempre podem ser reenviados pelo provedor?
Como eu sei se a duplicação vem do n8n ou do provedor?
Leia também
Como fazer idempotência em automações com webhook (e parar de duplicar pedidos, notas e leads)
Guia direto para aplicar idempotência em automações com webhook: chaves idempotentes, deduplicação, banco/planilha, retries e boas práticas para n8n/Make/Zapier.
Ler →
Webhook ou polling em automações: como escolher (sem perder eventos e sem estourar limites)
Guia direto para decidir entre webhook e polling: latência, confiabilidade, custo por execução, rate limit e como evitar duplicidades. Inclui tabela e checklist prático.
Ler →
Webhook no n8n: como receber, tratar e responder HTTP (sem gambiarra)
Aprenda a criar um webhook no n8n, validar assinatura, tratar payload, evitar duplicidade e responder HTTP 200/400/500 com padrão de produção.
Ler →
Rate limit, retry e backoff: como parar de quebrar automação em API (n8n, Make, Zapier)
Guia direto para lidar com rate limit (429), retries e backoff em automações com APIs. Aprenda padrões práticos para n8n, Make e Zapier e evite falhas intermitentes, duplicidades e banimentos.
Ler →