Guía de despliegue

n8n out of memory: diagnóstico y corrección en VPS

Desplegar en un VPS Cloud →

Tutorial

n8n out of memory: diagnóstico y corrección en VPS

Automatización9 min de lectura7 pasos

El mensaje `FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory` detiene n8n sin previo aviso. Muchos equipos añaden más RAM y no ven cambio alguno — porque el límite del heap V8 es independiente de la memoria física del servidor y debe configurarse explícitamente. Este artículo cubre las tres causas reales del crash OOM, la variable de entorno que corrige cada una, y la separación worker/webhook que evita recaídas.

Contenido· Por qué n8n falla por memoria, y no por la razón que crees1/8
  1. 01Por qué n8n falla por memoria, y no por la razón que crees
  2. 02Señales que confirman un crash OOM en n8n
  3. 03Requisitos previos antes de intervenir
  4. 04Corregir el OOM: del diagnóstico a la configuración estable
  5. 05Limitar el tamaño del payload de ejecución
  6. 06Configuración post-corrección: variables de entorno útiles
  7. 07Resolución de problemas — errores reales y sus causas
  8. 08Recursos y próximos pasos

Por qué n8n falla por memoria, y no por la razón que crees

V8, el motor JavaScript integrado en Node.js, tiene un límite de heap independiente de la RAM física. Por defecto oscila entre 512 MB y 1,5 GB según la versión de Node y la plataforma — en un VPS de 4 GB u 8 GB, la máquina no se queda sin memoria, pero el proceso V8 sí. Añadir más RAM al servidor no cambia nada sin NODE_OPTIONS=--max-old-space-size.

Segunda causa frecuente: en modo main (el predeterminado), n8n ejecuta los workflows en el mismo proceso que sirve los webhooks y la API. Un workflow pesado en datos — transformación CSV, agregación de miles de filas, llamadas GPT en bucle — monopoliza el heap durante su ejecución. Si varios se acumulan, se alcanza el límite V8 y el proceso se mata.

Tercera causa, más sutil: los jobs se acumulan en memoria cuando el modo queue está activado sin workers dedicados. La queue (Redis o BullMQ) descarga las ejecuciones del proceso principal, pero si ningún worker consume realmente los jobs, se acumulan, los callbacks permanecen en espera y el heap crece.

Señales que confirman un crash OOM en n8n

  • Mensaje de salida exacto: FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory en los logs del contenedor (docker logs n8n)
  • Crash silencioso bajo systemd: el servicio se reinicia automáticamente sin dejar rastro si Restart=always está activo — comprobar con journalctl -u n8n --since "1 hour ago"
  • OOM kill del kernel: dmesg | grep -i oom muestra Killed process <pid> (node) antes del reinicio, independientemente de Node
  • Correlación con un workflow pesado: el crash ocurre siempre durante ejecuciones de tipo «procesamiento de archivo» o «bucle sobre miles de elementos»
  • Heap estable durante horas y luego pico repentino: un workflow lanzado periódicamente acumula closures no liberadas — el heap sube en cada ejecución y no baja completamente
  • Carga de memoria normal en htop: la RAM del sistema no está saturada en el momento del crash, lo que confirma que el problema es V8, no la máquina

Requisitos previos antes de intervenir

Estos pasos asumen que n8n ya está corriendo en tu VPS mediante Docker Compose. Si no es así, el artículo installer-n8n-vps cubre el despliegue completo desde cero — vuelve aquí una vez la instancia esté en marcha.

Lo que necesitas para aplicar las correcciones:

- Acceso SSH root al VPS y fichero docker-compose.yml editable
- Memoria disponible: un límite V8 de 4096 MB (--max-old-space-size=4096) requiere al menos 6 GB de RAM en el VPS para dejar margen al sistema operativo, workers y Redis
- Redis ya desplegado si cambias al modo queue — redis:7-alpine es suficiente para uso en un solo VPS
- Versión n8n 1.0 o superior: la separación main/worker está disponible desde la versión 0.214 pero solo es estable en producción a partir de 1.0
- Copia de seguridad de la base de datos antes de cualquier modificación del Compose — las tablas de credentials y ejecuciones no forman parte de la imagen Docker

Corregir el OOM: del diagnóstico a la configuración estable

  1. Confirmar la causa en los logs

    Lee las últimas 200 líneas del contenedor en el momento del crash:

    docker logs n8n --tail 200 2>&1 | grep -E "FATAL|heap|OOM|Killed"

    Si ves FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory, es un crash V8. Si ves Killed solo sin mensaje Node, es el OOM killer del kernel — ambos pueden coexistir en el mismo incidente.

  2. Establecer el límite V8 mediante NODE_OPTIONS

    En tu docker-compose.yml, añade la variable de entorno NODE_OPTIONS al servicio n8n. Valor recomendado según la RAM del VPS:

    - VPS 4 GB: --max-old-space-size=2048
    - VPS 8 GB: --max-old-space-size=4096
    - VPS 16 GB: --max-old-space-size=8192

    Regla: reserva aproximadamente la mitad de la RAM disponible tras el sistema operativo y servicios auxiliares (Redis, proxy). No superar el 70% de la RAM total.

    services:
      n8n:
        image: n8nio/n8n:latest
        environment:
          - NODE_OPTIONS=--max-old-space-size=4096
          # ... otras variables
  3. Verificar que el valor se lee correctamente

    Tras docker compose up -d, verifica que Node lee el límite:

    docker exec n8n node -e "const v8=require('v8'); console.log(v8.getHeapStatistics().heap_size_limit / 1024 / 1024, 'MB')"

    El valor mostrado debe aproximarse a tu --max-old-space-size. Si sigue mostrando 512 o 1500, la variable de entorno no se está pasando al proceso — verifica que NODE_OPTIONS está en la sección environment: del servicio.

  4. Cambiar al modo queue con Redis

    El modo main (predeterminado) ejecuta todo en un único proceso. Para instancias que gestionan más de 20 workflows simultáneos o payloads voluminosos, separa los roles:

    services:
      redis:
        image: redis:7-alpine
        restart: unless-stopped
        volumes:
          - redis_data:/data
    
      n8n:
        image: n8nio/n8n:latest
        environment:
          - NODE_OPTIONS=--max-old-space-size=2048
          - EXECUTIONS_MODE=queue
          - QUEUE_BULL_REDIS_HOST=redis
          - QUEUE_BULL_REDIS_PORT=6379
        depends_on:
          - redis
        ports:
          - "5678:5678"
    
      n8n-worker:
        image: n8nio/n8n:latest
        command: worker
        environment:
          - NODE_OPTIONS=--max-old-space-size=4096
          - EXECUTIONS_MODE=queue
          - QUEUE_BULL_REDIS_HOST=redis
          - QUEUE_BULL_REDIS_PORT=6379
        depends_on:
          - redis
        scale: 2
    
    volumes:
      redis_data:

    El servicio n8n se convierte en el proceso principal (API + UI + webhooks) con un límite moderado. El servicio n8n-worker gestiona las ejecuciones con un límite mayor. La directiva scale: 2 lanza dos workers — ajusta según tus necesidades.

  5. Separar el proceso webhook si el tráfico lo requiere

    En instancias que reciben muchos webhooks en paralelo, el proceso principal puede saturarse incluso sin ejecutar workflows. n8n ofrece un modo webhook dedicado:

      n8n-webhook:
        image: n8nio/n8n:latest
        command: webhook
        environment:
          - NODE_OPTIONS=--max-old-space-size=1024
          - EXECUTIONS_MODE=queue
          - QUEUE_BULL_REDIS_HOST=redis
          - QUEUE_BULL_REDIS_PORT=6379
          - N8N_DISABLE_UI=true
        depends_on:
          - redis
        ports:
          - "5679:5678"

    Configura tu reverse proxy para enrutar /webhook/ al puerto 5679 y el resto al puerto 5678 del proceso principal. El modo webhook está disponible desde n8n 1.0.

  6. Activar el garbage collector explícito para workflows pesados

    Para workflows que procesan archivos grandes o bucles largos, puedes ayudar a V8 a liberar memoria de forma más agresiva:

    NODE_OPTIONS="--max-old-space-size=4096 --expose-gc"

    Esto expone global.gc() — n8n puede llamarlo entre los pasos de un workflow. Combínalo con EXECUTIONS_DATA_SAVE_ON_SUCCESS=none si no necesitas el historial de ejecución: los datos de ejecución retenidos suelen representar el 30-50% del heap.

  7. Monitorizar el heap tras la corrección

    Activa las métricas de n8n para observar la evolución del heap sin intervención manual:

    N8N_METRICS=true
    N8N_METRICS_PREFIX=n8n_

    El endpoint /metrics (puerto 5678) expone nodejs_heap_size_used_bytes y nodejs_heap_size_total_bytes, compatibles con Prometheus. Un dashboard básico de Grafana sobre estas dos métricas te alertará mucho antes del próximo crash.

Limitar el tamaño del payload de ejecución

El parámetro EXECUTIONS_DATA_MAX_SIZE (en bytes, sin límite por defecto) corta una ejecución antes de que pueda desbordar el heap. Valor recomendado para instancias de propósito general: 16777216 (16 MB). Un workflow que supere este umbral falla de forma limpia en lugar de matar todo el proceso. Combínalo con EXECUTIONS_DATA_PRUNE=true y EXECUTIONS_DATA_MAX_AGE=168 (una semana) para evitar la acumulación de datos de ejecuciones pasadas.

Configuración post-corrección: variables de entorno útiles

Una vez resuelto el OOM, estas variables consolidan la estabilidad de la instancia:

- N8N_DEFAULT_BINARY_DATA_MODE=filesystem — almacena los archivos binarios en disco en lugar de en memoria; indispensable para workflows que manipulan archivos CSV o PDF voluminosos
- OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true — las ejecuciones manuales (lanzadas desde el editor) también pasan por los workers, evitando presión sobre el heap del proceso principal durante las pruebas
- N8N_RUNNERS_ENABLED=true y N8N_RUNNERS_MAX_CONCURRENCY=5 — activa el task runner experimental (n8n 1.10+) que aísla cada ejecución en un subproceso, impidiendo que un único workflow consuma todo el heap disponible
- DB_POSTGRESDB_* — migrar de SQLite a PostgreSQL en instancias de alto volumen: SQLite serializa todas las lecturas/escrituras y puede bloquear a los workers, amplificando la presión de memoria

Resolución de problemas — errores reales y sus causas

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
Causa directa: el heap V8 ha alcanzado su límite. Solución: añadir NODE_OPTIONS=--max-old-space-size=<n> en las variables de entorno del contenedor, con un valor calibrado según la RAM disponible (ver paso 2).

Killed en los logs, sin mensaje Node
Causa: el OOM killer del kernel Linux ha terminado el proceso antes de que V8 pudiera emitir su mensaje. Ocurre cuando la memoria física está realmente agotada — distinto de un crash V8 puro. Verificar con dmesg | grep -i oom. Reducir --max-old-space-size o añadir RAM, y activar EXECUTIONS_DATA_SAVE_ON_SUCCESS=none.

Los workers no consumen jobs pese a EXECUTIONS_MODE=queue
Causa frecuente: DB_TYPE y las variables de base de datos no se pasan a los workers. Cada servicio del Compose debe tener sus propias variables de conexión. Verificar con docker exec n8n-worker env | grep DB_.

El heap sube tras cada ejecución y no baja
Causa: un closure retiene una referencia a un array grande entre ejecuciones. Activar --expose-gc en NODE_OPTIONS y añadir EXECUTIONS_DATA_SAVE_ON_SUCCESS=none. Si persiste, cambiar al modo task runner (N8N_RUNNERS_ENABLED=true).

Error: Redis connection failed tras cambiar al modo queue
Causa: QUEUE_BULL_REDIS_HOST apunta a localhost en lugar del nombre de servicio Docker. En una red Compose, el proceso principal y los workers alcanzan Redis por su nombre de servicio (redis en el ejemplo), no 127.0.0.1.

Recursos y próximos pasos

La documentación oficial de n8n sobre errores de memoria (docs.n8n.io/hosting/scaling/memory-errors) detalla los valores recomendados de --max-old-space-size según la RAM disponible y lista los parámetros de escalado. El issue de GitHub n8n-io/n8n#17461 (OOM en producción, abierto en marzo de 2026, 80+ comentarios) documenta casos reales — incluyendo la correlación entre workflows de procesamiento CSV y crash heap — y configuraciones que han estabilizado instancias similares a la tuya.

Si gestionas varias instancias de n8n para distintos clientes, la separación main/worker descrita aquí es también la base de una arquitectura multi-tenant: cada cliente puede tener su propio pool de workers con un límite V8 independiente, sin que un workflow pesado de una cuenta afecte a las demás.

Despliega n8n en un VPS dedicado

Un VPS con acceso root, IPv4 dedicada y elección de SO para alojar tu instancia n8n en modo queue, sin restricciones de workflows ni webhooks.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva