Forma de Evitar Execuções Duplicadas de Workflow a partir de Múltiplas Tentativas de Webhook

Oi a todos,
Estou enfrentando um problema de confiabilidade com fluxos de trabalho acionados por webhook no n8n.
Minha configuração é assim: Webhook → Processar Dados → Requisição HTTP → Banco de Dados
O serviço externo tenta novamente o webhook se não receber uma resposta rápida o suficiente, o que às vezes causa:
• Executar fluxos de trabalho duplicados
• Inserções duplicadas no BD
• Chamadas de API/emails duplicados
O payload inclui um ID de evento:
{
“event_id”: “evt_12345”,
“user_id”: 42
}
Atualmente, se o mesmo webhook for enviado duas vezes, ambas as execuções são executadas completamente.
Estou tentando descobrir a abordagem mais limpa para a produção:
• Desduplicação
• Evitar processamento simultâneo do mesmo evento
• Lidar com tentativas com segurança
Já considerei:
• Armazenar event_ids processados no BD
• Usar locks do Redis
• Processamento baseado em fila
• Retornar respostas de webhook imediatamente e processar de forma assíncrona
Para pessoas que lidam com sistemas de webhook de alto volume no n8n:
• Qual padrão funcionou melhor para evitar execuções duplicadas e efeitos colaterais?

*), entre em contato com o suporte em help@n8n.io

Qual é a mensagem de erro (se houver)?

Compartilhe seu fluxo de trabalho

(Selecione os nós na sua tela e use os atalhos de teclado CMD+C/CTRL+C e CMD+V/CTRL+V para copiar e colar o fluxo de trabalho.)

Compartilhe a saída retornada pelo último nó

Oi @Keira_Becky A abordagem mais confiável geralmente é: Webhook → Salvar/verificar event_id → Processar

A ideia principal é tratar event_id como um identificador único.

Armazene o event_id no seu banco de dados com uma restrição UNIQUE antes de processar qualquer coisa.

Exemplo: INSERT INTO webhook_events (event_id)
VALUES ({{$json.event_id}})
ON CONFLICT DO NOTHING;

Se a inserção for bem-sucedida → processe o workflow
Se já existir → pule-o

Isso ajuda a Previne processamento duplicado
Lida com retentativas de webhook com segurança
Evita emails/chamadas de API/inserções em BD duplicadas

Você também pode tentar retornar a resposta do webhook rapidamente e processar o trabalho pesado de forma assíncrona, se possível. Isso reduz retentativas do serviço externo.

Bem-vindo @Keira_Becky à nossa comunidade! Sou Jay e sou um criador verificado da n8n.

A abordagem de constraint único no banco de dados que Niffzy mencionou é sólida. Para uma abordagem pura de n8n sem configuração extra de DB, você pode usar $getWorkflowStaticData('global') para rastrear IDs de eventos processados diretamente no fluxo de trabalho - armazene o event_id em um nó Set para o objeto de dados estáticos, depois verifique em cada execução antes do processamento. Isso funciona para volumes moderados, mas não escala para alto throughput.

Para produção, a combinação mais limpa é: retornar a resposta do webhook imediatamente usando o nó Respond to Webhook (configurado para “Respond First”), depois continuar o processamento pesado após - isso corta a maioria das tentativas na origem. Adicione uma verificação de DB com constraint UNIQUE no event_id como Niffzy descreveu, e você cobrirá tanto a prevenção de retry quanto a deduplicação real. Se você estiver auto-hospedando com modo de fila ativado, também defina EXECUTIONS_TIMEOUT e limites de concorrência para evitar congestionamento durante picos.

Ótimo detalhamento do problema. Aqui está a abordagem de produção que usei e que atende claramente a todas as três preocupações suas:

1. Deduplicação baseada em banco de dados (sua melhor aposta para a maioria dos setups)

No início bem do seu workflow, antes de qualquer processamento, faça uma consulta no banco de dados usando event_id. Se existir uma linha com status processed ou processing, responda com 200 imediatamente e pare. Se nada for encontrado, insira uma linha com status processing — isso funciona como seu lock.

O segredo é fazer a inserção com uma restrição UNIQUE em event_id para que execuções concorrentes compitam para inserir e apenas uma vença. O perdedor recebe uma violação de restrição que você captura e sai de forma limpa.

2. Responda ao webhook imediatamente (nó Respond to Webhook)

Use o nó “Respond to Webhook” do n8n no início do seu workflow — antes do processamento pesado — para retornar 200 instantaneamente. Isso impede que o serviço externo expire o timeout e tente novamente em primeiro lugar. Depois continue o processamento na mesma execução. Isso sozinho elimina a maioria dos cenários de duplicação.

3. Modo de fila para proteção de concorrência verdadeira

Se você está auto-hospedado e precisa de deduplicação à prova de bala sob carga, execute o n8n em modo de fila (com Redis/Bull). Combinado com a verificação de BD acima, você obtém processamento serializado sem condições de corrida.

Recomendação prática:

  • Responda ao webhook cedo → elimina a maioria das tentativas na fonte
  • Verificação de dedup em BD com restrição UNIQUE → trata o resto
  • Locks Redis são excessivos a menos que você esteja processando milhares de eventos/min

A combinação de resposta rápida + writes de BD idempotentes é nível de produção e não requer Redis.