Caída de la instancia en la nube de n8n en el flujo de trabajo

Describe el problema/error/pregunta

Bloqueo de la instancia de nube de n8n en el flujo de trabajo.

Mi flujo de trabajo ha funcionado sin problemas durante los últimos 3 meses, pero ayer de repente falló 3 veces y n8n lo desactivó automáticamente. Ha habido incidentes donde el sistema falló más de 30 ejecuciones pero nunca se apagó. Este se desactivó después de solo 3. Además, reintenté 3 veces en los nodos donde falló, pero aún así se bloqueó debido a que se agotó el espacio de memoria. En la documentación, dice que n8n reiniciará la instancia automáticamente pero tampoco sucedió, así que manualmente la volví a iniciar después de un día hoy. ¿Qué precauciones puedo tomar para el futuro?

¿Cuál es el mensaje de error (si lo hay)?

Ejecución detenida en este nodo

n8n puede haberse quedado sin memoria mientras ejecutaba esta ejecución. Más contexto y consejos sobre cómo evitar esto en la documentación

Por favor comparte tu flujo de trabajo

(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 flujo de trabajo.)

Comparte el resultado devuelto por el último nodo

Información sobre tu configuración de n8n

  • Versión de n8n:
  • Base de datos (predeterminado: SQLite):
  • Configuración de n8n EXECUTIONS_PROCESS (predeterminado: own, main):
  • Ejecutando n8n a través de (Docker, npm, n8n cloud, aplicación de escritorio):
  • Sistema operativo:

Hola @Aarush_Bisht

Para prevenir bloqueos relacionados con la memoria, debes enfocarte en reducir la «huella de memoria» de tus datos mientras se mueven a través del flujo de trabajo.

A. Implementar Procesamiento por Lotes (El paso más importante) Si estás procesando una lista grande de elementos (p. ej., 1000+ filas de una base de datos o API), no los pases todos al siguiente nodo a la vez.

  • Utiliza el nodo “Split In Batches”: Procesa elementos en fragmentos más pequeños (p. ej., 50 o 100 a la vez). Esto garantiza que n8n solo mantenga un subconjunto pequeño de datos en memoria activa en cualquier momento dado.

B. Evita Datos «Pesados» en Memoria

  • Limita Campos: Utiliza un nodo Set o un nodo Edit Fields para eliminar datos innecesarios al principio del flujo de trabajo. Si una API devuelve 50 campos pero solo necesitas 3, elimina los otros 47 inmediatamente.
  • Gestión de Datos Binarios: Si estás tratando con archivos grandes (PDF, Imágenes), evita mantener múltiples copias de los datos binarios en el flujo de trabajo. Utiliza los nodos «Read/Write Binary File» o almacenamiento externo (como S3 o Google Drive) y pasa solo el ID del archivo o la URL entre nodos.

C. Optimizar la Ejecución de Nodos

  • Evita Bucles Grandes: Los bucles profundamente anidados o las llamadas recursivas pueden consumir rápidamente la memoria de pila y montón.
  • Nodos de Espera: Si estás llamando a una API en un bucle, añade un nodo Wait (aunque sea por 1 segundo). Esto no solo previene limitaciones de velocidad, sino que también puede darle al recolector de basura de Node.js una ventana para limpiar la memoria no utilizada.

D. Monitoreo y Alertas

  • Flujo de Trabajo de Error: Crea un «Flujo de Trabajo de Error» dedicado (a través de la Configuración del Flujo de Trabajo) que te envíe una notificación por Slack o Correo electrónico en el momento en que ocurra una falla. Esto te permite intervenir manualmente antes de que el sistema alcance el límite del «Circuit Breaker» y apague el flujo de trabajo.

Había estado funcionando bien durante meses pero se bloqueó/despublicó un día después de solo 3 fallos de ejecución. (He implementado 3 reintentos por nodo por ejecución). La cantidad de datos tampoco es mucha (literalmente solo 50-60 líneas de datos de empleados). También he implementado manejo de errores, he hecho «siempre enviar datos» y luego si se detecta un error me avisa. La parte interesante es que tampoco siguió eso. Ni siquiera intentó reintentar, simplemente falló y se despublicó.

¿Alguno de estos casos aplica:

  • Payload inesperadamente grande: ¿Alguno de esos 60 empleados tenía un campo (como una sección “Notas” o “Biografía”) que de repente contenía una cantidad masiva de texto o una imagen/archivo codificado en base64 gigante?
  • Respuesta “infinita” de API: ¿Alguna API externa que estés llamando devolvió un objeto JSON masivo (p. ej., 10MB+) para solo uno de esos 60 registros?
  • Referencia circular: ¿Los datos crearon un bucle que hizo que el motor de JavaScript alcanzara un límite de “Stack Overflow” u “Out of Memory”?

Revisa tus registros en la nube

  1. Verifica el historial de ejecuciones: Busca las 3 ejecuciones fallidas. ¿Tienen un estado de Error o simplemente están Running (atascadas) o desaparecidas por completo? Si faltan o están atascadas en “Running” a pesar de que el flujo de trabajo esté desactivado, confirma un bloqueo grave.
  2. Inspecciona los datos: Mira los datos que entraron en el flujo de trabajo ayer. Compáralo con días anteriores. Busca cadenas inusualmente grandes o formatos inesperados en esas 60 líneas.
  3. Busca nodos “pesados”: ¿Tienes algún nodo de código? Un pequeño error lógico en un nodo de código (como un bucle while infinito) puede consumir toda la RAM disponible en segundos, omitiendo todos los manejos de errores integrados de n8n.

50-60 líneas de datos correspondían a un empleado.
y uno de los 3 que fallaron era un nodo de código JavaScript donde estaba intentando reducir las dimensiones de los datos.
{
“nodes”: [
{
“parameters”: {
“jsCode”: “\nconst updates = $node[“Webhook”].json.body.data.fieldUpdatesIds.map(f =\ f.id);\n\nconst targetFields = [\n “work.site”,\n “work.department”,\n “work.siteId”,\n “work.customColumns.column_1732603686850”,\n “work.workChangeType”,\n “work.title”,\n “work.activeEffectiveDate”,\n “work.reportsTo”,\n “root.displayName”\n];\n\nconst check = updates.some(id =\ targetFields.includes(id));\n\nreturn [{ check}];\n”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [
-3104,
496
],
“id”: “7e8b7768-aa58-4218-98bb-24008a7ea4ef”,
“name”: “Code in JavaScript1”
}
],
“connections”: {
“Code in JavaScript1”: {
“main”: [

]
}
},
“pinData”: {},
“meta”: {
“instanceId”: “0f39d8fdd402ddce20d0eb724526828e8c2d8679170e3a08fe6cd471c799fab6”
}
}

Los registros de esas 3 ejecuciones en particular no se pueden verificar porque n8n dice que no se guardan registros debido al fallo en la ejecución. (extraño, ya que los registros de fallos son más importantes).
1 nodo falló que solo estaba ahí para obtener un token de autenticación. Sin bucle, solo una llamada API. El tercero (nodo HTTP) tenía algunas imageUrls en la respuesta pero no imágenes (basándome en ejecuciones anteriores). Los tres fallaron juntos en 3 ejecuciones diferentes con la misma razón.

¿Podría ser algún fallo en el lado del servidor de n8n?

Muy poco probable.

Tu código es lógicamente simple y no debería provocar que un servidor se bloquee con 60 líneas de datos. Sin embargo, hay un riesgo de rendimiento en cómo accede a los datos:

const updates = $node["Webhook"].json.body.data.fieldUpdatesIds.map(f => f.id);

Usar $node["NodeName"] obliga a n8n a mantener el objeto de datos completo del nodo anterior en el montón de memoria activa durante toda la ejecución del flujo de trabajo. Si tu carga útil de Webhook es grande y tienes múltiples nodos haciendo esto, estás multiplicando el uso de memoria.

Reemplaza tu código JS actual con esta versión. Utiliza la sintaxis moderna y añade una “comprobación de seguridad” para evitar que el nodo se bloquee si faltan los datos (lo que de otro modo causaría un TypeError):

// Usa la sintaxis moderna $(...).item para una mejor gestión de memoria
const webhookData = $("Webhook").item.json.body?.data?.fieldUpdatesIds;

if (!Array.isArray(webhookData)) {
    return [{ check: false, error: "No fieldUpdatesIds found" }];
}

const updates = webhookData.map(f => f.id);

const targetFields = [
 "work.site",
 "work.department",
 "work.siteId",
 "work.customColumns.column_1732603686850",
 "work.workChangeType",
 "work.title",
 "work.activeEffectiveDate",
 "work.reportsTo",
 "root.displayName"
];

const check = updates.some(id => targetFields.includes(id));

return [{ check }];

Para asegurar que realmente obtienes registros cuando algo sale mal:

  1. Ve a Configuración de flujo de trabajo (el icono de engranaje).
  2. Asegúrate de que “Guardar ejecuciones fallidas” esté ACTIVADO.
  3. Establece “Guardar ejecuciones exitosas” en DESACTIVADO (o “Solo si hay error”). Esto libera recursos de la base de datos y facilita la identificación de las ejecuciones “problemáticas”.

Ya que mencionaste que el nodo HTTP tenía imageUrls, comprueba si alguna de esas URLs está devolviendo metadatos masivos o si el cuerpo de la respuesta es inesperadamente grande. Incluso si no es la imagen en sí, una respuesta JSON enorme puede causar un pico de memoria.

Acabo de verificar las ejecuciones fallidas y fue una guardada por defecto. Los datos JSON solo tenían URLs de imágenes, nada más. También revisé los datos que todos los nodos están recibiendo del webhook (sí, ese nodo de código estaba procesando esos datos). Es un webhook de evento básico de Slack que recibe 20-30 líneas de metadatos de solicitud de API (en los encabezados) y 10 líneas de cuerpo e información adicional en JSON. (No parece haber nada malo). Mi problema es que si alguna vez me tomo un descanso y esto sucede, entonces el sistema podría estar caído por un tiempo.

Dos posibilidades:

  1. Fuga Acumulativa: Durante 3 meses, pequeñas cantidades de memoria podrían no haber sido liberadas correctamente. Eventualmente, el uso de memoria “base” se volvió tan alto que incluso un pequeño webhook de Slack lo empujó por encima del límite.
  2. Concurrencia: Si 5 o 10 eventos de Slack llegan a tu webhook en exactamente el mismo segundo, n8n inicia múltiples ejecuciones paralelas. Aunque cada una sea pequeña, 10 procesos simultáneos pueden causar un pico de RAM y desencadenar el bloqueo.

Ya que te preocupa que el sistema esté caído mientras estés de vacaciones, no puedes confiar en que n8n se monitoree a sí mismo (porque si falla, el monitor también falla). Necesitas Monitoreo Externo.

Usa un servicio gratuito como Better Stack, UptimeRobot o Cronitor.

  • Crea un segundo workflow muy simple en n8n: Webhook TriggerRespond to Webhook (200 OK).
  • Configura el monitor externo para hacer ping a esta URL cada 5 o 10 minutos.
  • Si el monitor recibe un error 500 o un timeout, te enviará un email/SMS inmediatamente. Sabrás que la instancia está caída antes de que tu workflow principal pierda datos críticos.

Mirando la captura de pantalla de tus configuraciones, tienes “Save successful production executions” configurado en “Save”.

  • Cambia esto a “Do not save”.
  • ¿Por qué? Cada vez que se guarda una ejecución exitosa, n8n tiene que mantener esos datos en memoria y escribirlos en el disco. Para un webhook de Slack de alta frecuencia, esto crea un “desgaste” constante en la memoria. Al guardar solo los fallos, reduces significativamente la carga en la instancia.

Ya que tus datos son objetivamente pequeños y has estado ejecutándote durante 3 meses, esto podría ser un problema con el “nodo” específico (el servidor físico) en el que está alojada tu instancia.

  • Envía a n8n cloud support o a help@n8n.io la captura de pantalla de la ejecución “Interrupted”.
  • Diles: “Mi workflow está procesando payloads muy pequeños de Slack, pero estoy viendo ejecuciones ‘Interrupted’ y el Circuit Breaker está desactivando mi flujo. ¿Pueden verificar si mi instancia está experimentando presión de memoria o si debería ser movida a un host diferente?”

¿Hay algo que pueda hacer para solucionar las fugas acumulativas? ¿Como reiniciar el flujo de trabajo o algo similar? Apagar después de iteraciones exitosas podría no ser una opción para mí (instancia de la empresa, por lo que necesito mantener registros completos al menos de los últimos días). La concurrencia posiblemente podría ser un problema ya que las 3 ejecuciones fallidas ocurrieron juntas (pero he visto que n8n maneje 8-10, incluso más a veces). Es posible que no se necesite monitoreo externo ya que n8n mismo envía un mensaje por correo electrónico indicando que lo desactivaron y somos informados. (¡Me refería a quién se lleva la laptop del trabajo de vacaciones! :face_with_tongue:)

Reiniciar el flujo en sí no borrará una fuga; el punto de reinicio es la instancia en ejecución o el worker. Para este caso, la pista más reveladora es que los tres fallos ocurrieron juntos, no que el nodo Code sea pesado.

Verifica una ventana, sin datos de empleados necesarios: ¿las tres ejecuciones del webhook de Slack comenzaron dentro de los mismos pocos segundos, y había otras ejecuciones en ejecución en ese momento? Si es así, el siguiente límite es una pequeña cola/puerta serie antes de la ruta de actualización de empleados, por lo que Slack se reconoce rápidamente pero solo se procesa un trabajo de actualización a la vez. Si estaban espaciados, trata como un incidente de Cloud/runtime y proporciona al soporte los tres ID de ejecución más la marca de tiempo de deshabilitación automática.

podría ser un problema de concurrencia. ¿hay alguna forma de lidiar con esto? ¿podemos retrasar las ejecuciones que llegan al mismo tiempo por un tiempo?

Yes, this will help

Sí, pero no pongas el retraso después de los nodos pesados. Si tres eventos de Slack ya iniciaron el flujo completo, un nodo Wait solo deja tres ejecuciones vivas al mismo tiempo.

Mantén la entrada de Slack pequeña: recibe el evento, reconócelo y coloca solo el ID/cuerpo del evento necesario para la actualización del empleado detrás de una puerta de uno a la vez. Luego procesa esa segunda parte en una cadencia o cola. Aún puedes mantener registros de ejecución; lo que debes reducir es el trabajo paralelo en la rama de actualización del empleado, no la retención de registros en sí.

Supongo que el evento ya era pequeño, ya que los datos del webhook no eran grandes (máximo 50-60 líneas de JSON) y solo necesitábamos algunos campos de él (lo que el nodo de código estaba realizando: reducción de dimensionalidad de datos). Es solo que la solicitud llegó en paralelo. He visto solicitudes HTTP recibiendo MBs de datos sin bloquearse. De todas formas, intentaré llevar esto al equipo de n8n (si es posible para mí). Gracias por la ayuda, intentaré implementar estas sugerencias en flujos de trabajo futuros.