Quando i workflow crescono e i webhook iniziano a “picchiare”, serve un’architettura robusta, scalabile e osservabile. La modalità queue n8n separa l’orchestrazione dall’esecuzione: il processo main accoda le esecuzioni su Redis, i processi worker n8n le consumano in parallelo, e tu puoi aumentare capacità semplicemente aggiungendo worker. In questa guida pratica vedrai come passare a modalità coda di n8n con Redis e PostgreSQL, quali variabili d’ambiente per queue mode impostare, come eseguire scaling orizzontale dei worker, come ottimizzare processori di webhook n8n con un load balancer, e come abilitare metriche /metrics e health check /healthz per un’osservabilità di livello. Chiudiamo con hardening (TLS su Redis, segreti), storage binari su S3, aggiornamenti a zero‑downtime e una checklist di troubleshooting dei stalled jobs e dei timeout.

📚 Nuovo a n8n? Parti dalla guida completa: cos'è n8n e come funziona.

[IMG: diagramma architettura: Client/Webhook → Load Balancer → n8n main/webhook processors → Redis (queue) → Worker xN → PostgreSQL/S3]

Architettura: main, worker, Redis e PostgreSQL (cosa fa chi)

La modalità coda di n8n introduce un pattern collaudato per scalare:

  • Main (orchestrazione): riceve webhook, schedula trigger e mette in coda le esecuzioni su Redis. Non esegue il workflow end‑to‑end quando EXECUTIONS_MODE=queue è attivo; delega ai worker.
  • Redis (message broker): memorizza i job in attesa e lo stato in esecuzione. È il “ponte” fra main e processi worker n8n.
  • Worker (esecuzione): uno o più processi “n8n worker” estraggono job dalla coda e li eseguono. Aumentare i worker = più throughput.
  • PostgreSQL (storage stato): archivia workflow, credenziali, esecuzioni e cronologia. In distribuito è la scelta consigliata rispetto a SQLite.
  • Webhook processors: istanze n8n dedicate che gestiscono esclusivamente ingressi webhook, aumentando la capacità di assorbire picchi con un load balancer per webhook n8n.

Perché funziona:

  • Isolamento: un picco di webhook non blocca l’orchestrazione; le esecuzioni girano sui worker.
  • Scalabilità lineare: aggiungi worker per crescere. Ogni worker è stateless.
  • Robustezza: se un worker cade, i job ritornano in coda; il main resta disponibile.

Dove memorizzare i file:

  • Archiviazione dei dati binari su S3 (o compatibili) evita I/O locale e facilita lo scaling multi‑istanza: imposta la modalità S3 e le credenziali del bucket.

[IMG: sequenza: Webhook → Redis → Worker → DB → (S3 per binari) → Output]

Variabili chiave e setup (Docker Compose pronto all’uso)

Ecco un setup minimo e sicuro con PostgreSQL come database per n8n, Redis come coda e tre ruoli n8n: main, worker e webhook.

.env (esempio)

N8N_ENCRYPTION_KEY=super-segreto-lungo
POSTGRES_PASSWORD=postgrespass
N8N_HOST=n8n.example.com
WEBHOOK_PUBLIC_URL=https://n8n.example.com/

docker-compose.yml

version: "3.8"
services:
  postgres:
    image: postgres:15
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: n8n
    volumes:
      - pg_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  n8n-main:
    image: n8nio/n8n:latest
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      - OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true
      - N8N_HOST=${N8N_HOST}
      - N8N_PORT=5678
      - WEBHOOK_URL=${WEBHOOK_PUBLIC_URL}
      - N8N_METRICS=true
      # S3 per binari (opzionale, consigliato in cluster)
      - N8N_DEFAULT_BINARY_DATA_MODE=s3
      - S3_BUCKET_NAME=n8n-bucket
      - S3_REGION=eu-central-1
      - S3_ENDPOINT=
      - S3_ACCESS_KEY=
      - S3_SECRET_KEY=
    ports:
      - "5678:5678"
    volumes:
      - n8n_data:/home/node/.n8n
    command: "n8n"

  n8n-worker:
    image: n8nio/n8n:latest
    depends_on:
      redis:
        condition: service_healthy
      postgres:
        condition: service_healthy
    environment:
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
    command: "n8n worker"
    scale: 2

  n8n-webhook:
    image: n8nio/n8n:latest
    depends_on:
      redis:
        condition: service_healthy
      postgres:
        condition: service_healthy
    environment:
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
      - N8N_HOST=${N8N_HOST}
      - N8N_PORT=5679
      - WEBHOOK_URL=${WEBHOOK_PUBLIC_URL}
    ports:
      - "5679:5679"
    command: "n8n webhook"
    # dietro un Load Balancer con path /webhook e /webhook-test

volumes:
  pg_data:
  redis_data:
  n8n_data:

Variabili d’ambiente per queue mode da conoscere

  • EXECUTIONS_MODE=queue abilita la coda.
  • QUEUEBULL* configura Redis (host, port, db, username/password, tls).
  • OFFLOADMANUALEXECUTIONSTOWORKERS=true sposta anche i run manuali sui worker.
  • N8NENCRYPTIONKEY condivisa fra tutte le istanze.
  • WEBHOOK_URL URL pubblico dei webhook (dietro LB).
  • N8N_METRICS=true abilita l’endpoint di metriche Prometheus su /metrics.

[IMG: screenshot configurazione Docker Compose con evidenza su EXECUTIONSMODE e QUEUEBULL_*]

Tuning: concorrenza dei worker, processori di webhook e trigger di scaling

Concorrenza dei worker

  • Scaling orizzontale dei worker: aumenta replicas del servizio “n8n-worker” per incrementare throughput. Ogni replica consuma job dalla coda.
  • Pacing e backpressure: monitora la profondità della coda e la latenza p95/p99 delle esecuzioni; se la coda cresce e la latenza peggiora, scala.
  • Auto‑scaling: in Kubernetes, crea HPA basato su CPU e sulla metrica “jobs in queue” (esposta da Redis o dal tuo exporter).

Processori di webhook n8n

  • Se ricevi molti webhook simultanei, separa n8n-webhook dal main e mettilo dietro un load balancer per webhook n8n.
  • Aumenta le repliche di “n8n webhook” per assorbire burst. Il main rimane leggero, dedicato all’orchestrazione.
  • Assicurati che WEBHOOK_URL punti all’endpoint pubblico del LB; aggiorna DNS/SSL di conseguenza.

Trigger di scaling (pragmatici)

  • CPU media > 70% sui worker per >5 min
  • Profondità coda > (worker × 10) per >5 min
  • Latenza p95 > SLO (es. 2× il target) per >5 min
  • Error rate o stalled jobs in aumento

Timeout e stalled jobs nella coda

  • Imposta tempi di shutdown puliti (N8NGRACEFULSHUTDOWN_TIMEOUT) per permettere ai worker di completare job in corso.
  • Monitora “stalled jobs” (Bull/BullMQ) e analizza cause: latenze Redis, crash worker, job lunghi oltre lock TTL. Tuning disponibile nel namespace QUEUEBULL* (lock/renew/timeout).

[IMG: dashboard con queue depth, worker CPU, p95 latency e counter “stalled jobs”]

Alta disponibilità, metriche e hardening (TLS, segreti, S3)

Multi‑main e alta disponibilità n8n

  • Abilita multi‑main e leader election con le variabili N8NMULTIMAINSETUP* per evitare single‑point‑of‑failure del main.
  • I main condividono il DB e coordinano l’orchestrazione; mantieni un numero contenuto (es. 2‑3) dietro un LB.

Metriche /metrics e health check /healthz

  • Esponi /healthz per i readiness/liveness probe dei container e per i check del LB.
  • Abilita /metrics e raccogli con Prometheus/Grafana: esecuzioni per minuto, tempi medi/p95, error rate, queue depth, Redis e PostgreSQL health.

Hardening

  • Redis con TLS e password: configura QUEUEBULL* per tls e credenziali; vieta l’accesso pubblico a Redis e Postgres.
  • Segreti: solo via variabili sicure o secret manager; niente segreti nei repo. Usa campi password nelle credenziali n8n.
  • Archiviazione dei dati binari su S3: evita filesystem locale in cluster. Configura bucket, region, access/secret key e (opzionale) endpoint per S3 compatibile.
  • Aggiornamenti a zero‑downtime: rolling update per main, webhook e worker; mantieni WEBHOOKURL costante dietro LB; imposta N8NGRACEFULSHUTDOWNTIMEOUT per chiudere senza perdere job.

[IMG: schema HA: LB → main x2, webhook xN, worker xN, Redis/PG HA gestiti dal provider]

Migrare da istanza singola a modalità coda (senza fermare tutto)

Strategia in 6 passi
1) Passa a PostgreSQL: prepara il DB, configura DBTYPE=postgresdb e variabili DBPOSTGRESDB*. Migra lo schema se eri su SQLite.
2) Introduci Redis: avvia il servizio e verifica reachability/health.
3) Allinea i segreti: imposta N8N
ENCRYPTIONKEY e replica su tutte le istanze n8n.
4) Avvia n8n-main con EXECUTIONS
MODE=queue: verifica /healthz e l’accesso all’UI.
5) Aggiungi uno o più n8n-worker: monitora logs, /metrics e l’esecuzione di workflow semplici.
6) Separa i webhook: alza n8n-webhook dietro un LB puntando WEBHOOK_URL all’endpoint pubblico. Testa workflow con trigger Webhook (test e produzione).

Test e rollback

  • Esegui workflow sintetici (HTTP Request + Wait + Set) per misurare latenza e throughput.
  • Conserva la vecchia istanza in standby per qualche giorno. In caso di problemi, reindirizza temporaneamente il traffico.

[IMG: checklist di migrazione con spunte per DB, Redis, main, worker, webhook, LB]

Troubleshooting: errori frequenti e fix rapidi

  • Redis non raggiungibile (ECONNREFUSED): verifica QUEUEBULLREDIS_HOST/PORT e security group/firewall. Se TLS è richiesto, abilitalo esplicitamente.
  • “Encryption key mismatch”: N8NENCRYPTIONKEY non identica tra le istanze. Allinea e riavvia.
  • Manual runs lenti/bloccati: imposta OFFLOADMANUALEXECUTIONSTOWORKERS=true per farli consumare ai worker.
  • 502/504 sui webhook: LB non instrada a n8n-webhook o /webhook-url errata. Allinea WEBHOOK_URL, health probe e stickiness se servono.
  • Stalled jobs in aumento: worker saturi o lock TTL insufficiente. Aggiungi worker, riduci durata job (spezza in step), rivedi i parametri di lock/renew nel namespace QUEUEBULL*.
  • Disco pieno per binari: passa a archiviazione su S3 e imposta retention per le esecuzioni (policy di cleanup).

[IMG: tabella “Sintomo → Causa → Azione” con 6 righe principali]

Esempio end‑to‑end: dal webhook a 3 worker con report e alert

Scenario

  • Webhook riceve un ordine, arricchisce via API e scrive su DB/Sheet. Al contempo invia email e Slack.

Blueprint

  • n8n-webhook (repliche 2) dietro LB → Redis
  • n8n-worker (repliche 3) → esecuzione parallela dei job
  • PostgreSQL per stato/esecuzioni
  • S3 per binari (es. allegati ordine)
  • Prometheus → /metrics di main/worker/webhook con alert su p95 e queue depth

Pseudoflusso
1) Trigger Webhook → rispondi 200 veloce (onReceived)
2) Job in coda → worker consuma
3) HTTP Request a ERP → merge dati → scrittura DB/Sheets
4) Email (Gmail/Outlook) e Slack alert
5) Logging KPI nel DB/Sheet “Esecuzioni”

Questo disaccoppiamento gestisce burst di ordini senza perdere richieste né sovraccaricare l’istanza.

[IMG: canvas concettuale con icone Webhook → Redis → Worker x3 → DB/Sheets/Email/Slack]

Quick Takeaways

  • La modalità queue n8n separa orchestrazione (main) da esecuzione (worker) usando Redis: è la base per scalare in sicurezza.
  • Imposta EXECUTIONSMODE=queue, QUEUEBULL* per Redis e OFFLOADMANUALEXECUTIONSTO_WORKERS; usa PostgreSQL come database per n8n.
  • Scala aggiungendo worker e processori webhook dietro un load balancer; monitora CPU, queue depth e p95 per decidere quando crescere.
  • Abilita /healthz e /metrics per osservabilità e auto‑scaling; pianifica alert su errori e stalled jobs.
  • Proteggi Redis con TLS/password, gestisci segreti, e usa S3 per i binari in ambienti distribuiti.
  • Migra gradualmente: DB→Redis→main→worker→webhook, con test e rollback pronti.

Conclusione

Scalare n8n con la modalità coda significa adottare un’architettura moderna e resiliente: main leggero che orchestra, processi worker n8n che eseguono in parallelo e Redis come coda affidabile. Con PostgreSQL al posto di SQLite, i dati di workflow ed esecuzioni restano consistenti anche in scenari multi‑istanza. Aggiungendo processori di webhook n8n dietro un load balancer puoi assorbire picchi improvvisi, mentre metriche /metrics e health check /healthz rendono l’ecosistema osservabile e pronto per l’autoscaling. L’hardening con TLS su Redis, la gestione rigorosa dei segreti e l’archiviazione dei dati binari su S3 completano un assetto produttivo e sicuro. Se vuoi migliorare la produttività del team marketing e operations, parti da un MVP in queue mode, monitora p95 e queue depth, poi scala i worker quando serve: la tua automazione crescerà con il business senza sacrificare affidabilità, tempi di risposta e controllo dei costi.

FAQ

  • Cos’è la modalità coda di n8n e quando usarla?

  • È un’architettura in cui il main accoda esecuzioni su Redis e i processi worker n8n le consumano. Usala quando hai volumi elevati, webhook concorrenti o necessità di alta disponibilità.

  • Quali variabili d’ambiente per queue mode sono fondamentali?

  • EXECUTIONSMODE=queue, QUEUEBULL* (host/port/db/username/password/tls), OFFLOADMANUALEXECUTIONSTOWORKERS, N8NENCRYPTIONKEY condivisa e WEBHOOKURL per gli ingressi pubblici.

  • Come incremento la capacità di esecuzione?

  • Con scaling orizzontale dei worker (più repliche “n8n worker”) e processori di webhook n8n dedicati dietro load balancer. Monitora CPU, profondità coda e p95.

  • Devo usare PostgreSQL e S3?

  • Sì, PostgreSQL come database per n8n è consigliato in distribuito. Per i binari, l’archiviazione dei dati binari su S3 evita colli di bottiglia del filesystem locale e semplifica lo scaling.

  • Come monitoro salute e prestazioni?

  • Abilita metriche /metrics e health check /healthz, raccogli con Prometheus/Grafana e imposta alert su errori, queue depth e stalled jobs nella coda. Pianifica aggiornamenti a zero‑downtime.

Hai domande o vuoi condividere la tua esperienza di scaling con n8n? Racconta quali metriche monitori per prime e condividi questo articolo con il tuo team: qual è l’anello debole che vuoi potenziare subito (worker, webhook o storage)?

Vuoi automazioni AI su misura per la tua azienda?
Scopri la consulenza →