Hola a todos,
Me estoy encontrando con un problema de confiabilidad en los flujos de trabajo activados por webhooks en n8n.
Mi configuración se ve así: Webhook → Procesar datos → Solicitud HTTP → Base de datos
El servicio externo reintenta el webhook si no obtiene una respuesta lo suficientemente rápida, lo que a veces causa:
• Ejecuciones de flujo de trabajo duplicadas
• Inserciones duplicadas en BD
• Llamadas API/correos electrónicos duplicados
La carga útil incluye un ID de evento:
{
“event_id”: “evt_12345”,
“user_id”: 42
}
Ahora mismo, si se envía el mismo webhook dos veces, ambas ejecuciones se ejecutan completamente.
Estoy tratando de determinar el enfoque más limpio para producción en cuanto a:
• Deduplicación
• Evitar el procesamiento concurrente del mismo evento
• Manejar reintentos de forma segura
He considerado:
• Almacenar event_ids procesados en BD
• Usar bloqueos de Redis
• Procesamiento basado en colas
• Devolver respuestas de webhook inmediatamente y procesar de forma asincrónica
Para quienes manejan sistemas de webhooks de alto volumen en n8n:
• ¿Qué patrón ha funcionado mejor para prevenir ejecuciones duplicadas y efectos secundarios?
), por favor contacte al soporte en help@n8n.io →
¿Cuál es el mensaje de error (si hay alguno)?
Por favor, comparta su flujo de trabajo
(Seleccione los nodos en su lienzo y use los atajos de teclado CMD+C/CTRL+C y CMD+V/CTRL+V para copiar y pegar el flujo de trabajo.)
Comparta el resultado devuelto por el último nodo
Información sobre su configuración de n8n
- Versión de n8n:
- Base de datos (predeterminada: SQLite):
- Configuración de n8n EXECUTIONS_PROCESS (predeterminada: own, main):
- Ejecutando n8n mediante (Docker, npm, n8n cloud, aplicación de escritorio):
- Sistema operativo:
Hola @Keira_Becky El enfoque más confiable generalmente es: Webhook → Guardar/verificar event_id → Procesar
La idea clave es tratar event_id como un identificador único.
Guarda el event_id en tu base de datos con una restricción UNIQUE antes de procesar nada.
Ejemplo: INSERT INTO webhook_events (event_id)
VALUES ({{$json.event_id}})
ON CONFLICT DO NOTHING;
Si la inserción tiene éxito → procesa el flujo de trabajo
Si ya existe → omítelo
Esto ayuda a:
- Prevenir el procesamiento duplicado
- Gestionar reintentos de webhook de forma segura
- Detener correos electrónicos/llamadas API/inserciones de BD duplicadas
También puedes intentar devolver la respuesta del webhook rápidamente y procesar el trabajo pesado de forma asincrónica si es posible. Eso reduce los reintentos del servicio externo.
¡Bienvenida @Keira_Becky a nuestra comunidad! Soy Jay y soy un creador verificado de n8n.
El enfoque de restricción única de DB que mencionó Niffzy es sólido. Para un enfoque puro de n8n sin configuración adicional de DB, puedes usar $getWorkflowStaticData('global') para rastrear los IDs de eventos procesados directamente en el flujo de trabajo - almacena el event_id en un nodo Set a los datos estáticos, luego verifica en cada ejecución antes de procesar. Esto funciona para volúmenes moderados pero no escala a alto rendimiento.
Para producción, la combinación más limpia es: devolver la respuesta del webhook inmediatamente usando el nodo Respond to Webhook (configurado en “Respond First”), luego continuar con el procesamiento pesado después - esto evita la mayoría de reintentos en la fuente. Superpón un control de DB con una restricción UNIQUE en event_id como describió Niffzy, y habrás cubierto tanto la prevención de reintentos como la deduplicación real. Si estás alojando tú mismo con el modo de cola habilitado, también configura EXECUTIONS_TIMEOUT y límites de concurrencia para evitar acumulaciones durante picos.
Excelente desglose del problema. Aquí está el enfoque de producción que he utilizado y que aborda claramente las tres preocupaciones que mencionaste:
1. Deduplicación basada en BD (tu mejor opción para la mayoría de configuraciones)
Al inicio de tu flujo de trabajo, antes de cualquier procesamiento, realiza una búsqueda en la base de datos en event_id. Si existe una fila con estado processed o processing, responde con 200 inmediatamente y detente. Si no encuentras nada, inserta una fila con estado processing — esto actúa como tu bloqueo.
La clave es hacer la inserción con una restricción UNIQUE en event_id para que las ejecuciones concurrentes compitan por insertar y solo una gane. La perdedora obtiene una violación de restricción que captura y sale limpiamente.
2. Responder al webhook inmediatamente (nodo Respond to Webhook)
Usa el nodo “Respond to Webhook” de n8n temprano en tu flujo de trabajo — antes del procesamiento pesado — para devolver 200 al instante. Esto evita que el servicio externo agote el tiempo de espera y reintente en primer lugar. Luego continúa procesando en la misma ejecución. Esto solo elimina la mayoría de escenarios duplicados.
3. Modo de cola para verdadera protección de concurrencia
Si estás autohospedando y necesitas deduplicación a prueba de balas bajo carga, ejecuta n8n en modo de cola (con Redis/Bull). Combinado con la verificación de BD anterior, obtienes procesamiento serializado sin condiciones de carrera.
Recomendación práctica:
- Responde al webhook temprano → elimina la mayoría de reintentos en la fuente
- Verificación de dedup de BD con restricción UNIQUE → maneja el resto
- Los bloqueos de Redis son excesivos a menos que estés procesando miles de eventos/min
La combinación de respuesta rápida + escrituras idempotentes en BD es de nivel producción y no requiere Redis.