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.
[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 N8NENCRYPTIONKEY e replica su tutte le istanze n8n.
4) Avvia n8n-main con EXECUTIONSMODE=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)?
Scopri la consulenza →

