Hola a todos,
Estoy ejecutando n8n en modo de cola con múltiples workers, y estoy viendo un problema extraño después de reiniciar workers o deployments.
Mi configuración: Webhook → Queue → Worker → Process → Database
A veces después de reiniciar un worker:
Los trabajos antiguos se procesan nuevamente
Algunos trabajos aparecen “atascados” y luego se reintentan inesperadamente
Algunas ejecuciones crean escrituras duplicadas en BD/llamadas API
Ya uso reintentos y manejo de errores básico, pero creo que el problema está relacionado con cómo se reconocen o recuperan los trabajos después de fallos del worker.
Lógica de procesamiento de ejemplo:
if ($json.status !== “processed”) {
// continuar procesando
}
Estoy intentando entender:
• Cómo el modo de cola de n8n maneja trabajos inacabados después del reinicio
• Si los trabajos se vuelven a encolar automáticamente
• La mejor forma de hacer que los workflows sean seguros contra ejecución duplicada después de fallos
Para personas que usan modo de cola en producción:
• ¿Cuál es el patrón recomendado para recuperación de fallos y procesamiento idempotente?
Describe el problema/error/pregunta
¿Cuál es el mensaje de error (si hay alguno)?
Por favor, comparte tu workflow
(Selecciona los nodos en tu lienzo y usa los atajos de teclado CMD+C/CTRL+C y CMD+V/CTRL+V para copiar y pegar el workflow.)
Comparte el resultado devuelto por el último nodo
Información sobre tu configuración de n8n
Versión de n8n:
Base de datos (predeterminada: SQLite):
Configuración de n8n EXECUTIONS_PROCESS (predeterminada: own, main):
Ejecutando n8n a través de (Docker, npm, n8n cloud, aplicación de escritorio):
Hola @Decoure_Ryan Lo que estás viendo es generalmente un comportamiento normal en modo de cola. Si un worker se bloquea o reinicia antes de que un trabajo se complete/reconozca completamente, la cola puede marcar ese trabajo como no finalizado y reprocesarlo más tarde. Por eso ves que los trabajos antiguos se ejecutan de nuevo.
Intenta asumir que los trabajos pueden ejecutarse más de una vez y haz que el procesamiento sea idempotente.
Por ejemplo, antes de procesar:
if ($json.status === “processed”) {
return ;
}
Y usa protección a nivel de base de datos como:
ON CONFLICT DO NOTHING
o claves únicas para prevenir inserciones duplicadas.
Formas comunes que puedes aplicar en producción
La cola maneja reintentos/recuperación
La base de datos maneja deduplicación/idempotencia
Los workers permanecen sin estado
¡Bienvenido @Decoure_Ryan a nuestra comunidad! Soy Jay y soy un creador verificado de n8n.
Para añadir lo que dijo Niffzy - la causa raíz es el mecanismo de recuperación de “trabajos estancados” de Bull. Cuando un worker se reinicia sin completar un trabajo correctamente, Bull marca ese trabajo como estancado después de QUEUE_BULL_STALLED_INTERVAL milisegundos (por defecto 30000ms) y lo vuelve a encolar. Puedes ajustar esto con QUEUE_BULL_MAX_STALLED_COUNT=1 para limitar cuántas veces se reintenta un trabajo estancado, y QUEUE_BULL_STALLED_INTERVAL para controlar la ventana de detección. Para idempotencia a nivel de n8n, usa $getWorkflowStaticData o una verificación de estado en BD al inicio del flujo de trabajo para cancelar la ejecución si el execution_id ya fue procesado. Establecer una restricción única en execution_id en tu BD es la salvaguarda más confiable.
Redis actúa como broker y los workers ejecutan los jobs, pero no asumiría garantía de exactly-once; después de un crash/restart, trátalo como at-least-once, revisa N8N_GRACEFUL_SHUTDOWN_TIMEOUT y diseña el workflow para manejar el reprocesamiento.
(no estoy gritando es para dar más énfasis )
SIEMPRE USA CLAVE ÚNICA
El 99% de los problemas podrían resolverse con esto
Excelente análisis de @syed_noor. Una cosa que añadiría: BullMQ también tiene una configuración lockDuration (30s por defecto) — si tu flujo de trabajo tarda más que eso, el bloqueo expira y el trabajo se marca como estancado incluso mientras se sigue ejecutando. Puedes aumentarlo mediante QUEUE_BULL_STALLED_INTERVAL como se menciona, pero también asegúrate de que lockDuration esté configurado adecuadamente en tu configuración de BullMQ.
También vale la pena señalar — el enfoque de clave de idempotencia de Postgres es el patrón más confiable que he visto en producción. Combínalo con el nodo “Stop and Error” (Detener y Error) de n8n después de la verificación INSERT para salir limpiamente de las ejecuciones duplicadas sin contaminar tus registros de errores.
Buena adición sobre la distinción de lockDuration — debería haberlo señalado por separado. QUEUE_BULL_STALLED_INTERVAL controla con qué frecuencia se ejecuta el verificador, pero lockDuration controla cuánto tiempo puede estar activo un trabajo antes de que se considere estancado. Ambos deben ser superiores a tu tiempo de ejecución de flujo de trabajo más largo.
El consejo del nodo Stop y Error también es sólido. Lo uso después del INSERT de idempotencia con el mensaje configurado al job_id — de esa manera, cuando revises ejecuciones en n8n, puedes ver inmediatamente cuáles fueron duplicados legítimos versus fallos reales. Mantiene la lista de ejecuciones limpia en lugar de mostrar errores falsos positivos.
Para quien implemente este patrón, escribí un desglose más detallado de las seis dimensiones de preparación para producción (idempotencia es solo una de ellas) aquí:
El job_id en el mensaje Stop y Error es un toque inteligente - hace que el triage sea mucho más rápido cuando estás analizando ejecuciones. Otra cosa que vale la pena añadir sobre este patrón: establece el continueOnFail en el nodo de verificación de idempotencia y dirige la ruta “ya procesado” a un nodo No-op con un nombre claro (por ejemplo, “DUPLICATE - skipped”), en lugar de confiar únicamente en la ruta de error. Mantiene el gráfico de ejecución legible y separa los saltos esperados de las fallas reales de un vistazo.