n8n Queue Mode Setup
Queue mode enables distributed execution in n8n by separating the main node (UI/API) from worker nodes (execution) and webhook nodes (webhook processing). This architecture provides better scalability, reliability, and performance for production workloads.
Production Architecture: Queue mode is the recommended architecture for production deployments. It provides better scalability, reliability, and performance compared to single-node deployments.
Architecture Overview
Distributed Execution: Queue mode separates concerns by dedicating specific nodes to different tasks, improving overall system performance and reliability.
Queue Mode Components
Component Roles
- Main Node: Handles UI, API requests, workflow management
- Worker Nodes: Execute workflows and process tasks
- Webhook Nodes: Process incoming webhook requests
- Redis: Message broker for communication between nodes
Queue Mode Endpoints
Enhanced Endpoints: Queue mode supports additional endpoints for advanced workflow automation and AI integration capabilities.
MCP (Model Context Protocol) Endpoints
Queue mode includes support for MCP (Model Context Protocol) endpoints, enabling n8n to act as an MCP server for AI model integration:
- MCP Endpoint:
https://yourdomain.com/mcp/
- Main MCP server endpoint - MCP Test Endpoint:
https://yourdomain.com/mcp-test/
- Testing endpoint for MCP functionality
AI Integration: MCP endpoints allow AI models and assistants to interact with n8n workflows through the Model Context Protocol, enabling advanced AI-powered automation scenarios.
MCP Server Trigger Node
The MCP Server Trigger node allows n8n to expose workflows as tools to MCP clients:
- Server-Sent Events (SSE): Supports long-lived connections for real-time communication
- Streamable HTTP: Alternative transport method for MCP communication
- Authentication: Bearer token and header-based authentication support
- Tool Integration: Connect workflows with AI assistants and language models
MCP Requirements: MCP endpoints require PostgreSQL database and queue mode configuration. They are not available in single-node deployments with SQLite.
MCP Configuration Example
# Enable MCP endpoints in queue mode
webhook:
mode: queue
url: "https://yourdomain.com"
count: 2
mcp:
enabled: true
# You can add extra env vars, affinity, resources, etc. under webhook.mcp
ingress:
enabled: true
hosts:
- host: yourdomain.com
paths:
- path: /
pathType: Prefix
MCP Client Integration (Claude Desktop, Cursor, etc.)
Supergateway runs MCP stdio-based servers over SSE (Server-Sent Events) with one command. Please download your MCP client (Claude Desktop, Cursor, etc.) and apply the following configuration from client settings.
https://webhook.myhost/mcp/ab123c45-d678-9d0e-fg1a-2345bcd6ef7g
url must be replaced with your MCP Server Trigger Production URL
.
Basic MCP Client Settings
{
"mcpServers": {
"command": "npx",
"args": [
"-y",
"supergateway",
"--sse",
"https://webhook.myhost/mcp/ab123c45-d678-9d0e-fg1a-2345bcd6ef7g"
]
}
}
With Header Authentication
{
"mcpServers": {
"command": "npx",
"args": [
"-y",
"supergateway",
"--sse",
"https://webhook.myhost/mcp/ab123c45-d678-9d0e-fg1a-2345bcd6ef7g",
"--header",
"mykey:myvalue"
]
}
}
- You can set these in Claude Desktop, Cursor, or any compatible MCP client.
- Header authentication is supported for secure access.
Authentication:
- Use
--header
to pass custom authentication headers (e.g., API keys, tokens). - You can also use Bearer tokens if your n8n instance is configured for it.
MCP Documentation: For detailed MCP setup and usage, see the official n8n MCP documentation.
Form Endpoints
Queue mode supports dedicated form endpoints for the n8n Form Trigger node:
- Form Endpoint:
https://yourdomain.com/form/
- Main form submission endpoint - Form Test Endpoint:
https://yourdomain.com/form-test/
- Testing endpoint for forms - Form Waiting Endpoint:
https://yourdomain.com/form-waiting/
- Endpoint for form waiting workflows
Form Automation: Form endpoints enable the creation of interactive forms that can trigger n8n workflows, allowing users to submit data through web forms.
Form Trigger Node
The Form Trigger node creates web forms that can:
- Collect User Input: Gather data through customizable web forms
- Trigger Workflows: Automatically start workflows when forms are submitted
- Data Processing: Process form submissions and route data to other nodes
- User Experience: Provide a user-friendly interface for workflow interaction
Form Configuration Example
# Enable form endpoints in queue mode
webhook:
mode: queue
url: "https://yourdomain.com"
count: 2
ingress:
enabled: true
hosts:
- host: yourdomain.com
paths:
- path: /
pathType: Prefix
Form Documentation: For detailed form setup and usage, see the official n8n Form Trigger documentation.
Endpoint Routing
In queue mode, different endpoints are routed to appropriate nodes:
- Main Node: Handles UI, API, and test endpoints
- Webhook Nodes: Process webhook, form, and MCP endpoints
- Worker Nodes: Execute workflows triggered by any endpoint
Load Distribution: This routing ensures optimal performance by directing traffic to the appropriate node types based on the request type.
Prerequisites
Requirements: Queue mode requires PostgreSQL and Redis. SQLite is not supported for queue mode deployments.
Required Components
- PostgreSQL Database (required for queue mode)
- Redis Instance (message broker)
- Kubernetes Cluster with sufficient resources
- Storage Class for persistent volumes
Resource Requirements
- Main Node: 100m CPU, 128Mi memory minimum
- Worker Nodes: 500m CPU, 512Mi memory minimum per node
- Webhook Nodes: 100m CPU, 128Mi memory minimum per node
- Redis: 100m CPU, 128Mi memory minimum
Basic Queue Mode Setup
Getting Started: Start with a basic queue mode setup and scale up as needed based on your workload requirements.
1. Enable PostgreSQL
db:
type: postgresdb
postgresql:
enabled: true
auth:
username: n8n
password: your-secure-password
database: n8n
primary:
persistence:
enabled: true
size: 10Gi
2. Enable Redis
redis:
enabled: true
architecture: standalone
master:
persistence:
enabled: true
size: 5Gi
3. Configure Worker Nodes
worker:
mode: queue
count: 2
concurrency: 10
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
4. Configure Webhook Nodes
webhook:
mode: queue
url: "https://webhook.yourdomain.com"
count: 2
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 512m
memory: 512Mi
5. Complete Basic Configuration
# Basic queue mode setup
db:
type: postgresdb
postgresql:
enabled: true
auth:
username: n8n
password: your-secure-password
database: n8n
primary:
persistence:
enabled: true
size: 10Gi
redis:
enabled: true
architecture: standalone
master:
persistence:
enabled: true
size: 5Gi
worker:
mode: queue
count: 2
concurrency: 10
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
webhook:
mode: queue
url: "https://webhook.yourdomain.com"
count: 2
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 512m
memory: 512Mi
ingress:
enabled: true
hosts:
- host: n8n.yourdomain.com
paths:
- path: /
pathType: Prefix
Advanced Queue Mode Configuration
Scaling Strategy: Use autoscaling for dynamic workloads and manual scaling for predictable, steady-state workloads.
Autoscaling Workers (HPA)
Worker nodes execute workflows and process tasks from the Redis queue. Autoscaling worker pods ensures optimal performance during high workflow execution periods while reducing resource costs during low activity.
worker:
mode: queue
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
Worker Autoscaling: Horizontal Pod Autoscaler (HPA) automatically scales worker pods based on CPU and memory utilization metrics. Workers handle workflow execution, so scaling them ensures optimal performance during high workload periods while reducing costs during low activity. The behavior configuration controls scaling aggressiveness and stabilization periods.
Autoscaling Webhooks (HPA)
Webhook nodes handle incoming webhook requests and form submissions. Autoscaling webhook pods ensures optimal performance during high webhook traffic while reducing resource usage during low activity periods.
webhook:
mode: queue
url: "https://webhook.yourdomain.com"
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: packets-per-second
target:
type: AverageValue
averageValue: 1k
Webhook Autoscaling: Horizontal Pod Autoscaler (HPA) automatically scales webhook pods based on CPU utilization and network traffic metrics. Webhook nodes are lightweight and handle HTTP requests, making them ideal for autoscaling based on incoming traffic patterns.
Deploy on All Nodes
worker:
mode: queue
allNodes: true # Deploy one worker per node
autoscaling:
enabled: false # Disable autoscaling when using allNodes
webhook:
mode: queue
url: "https://webhook.yourdomain.com"
allNodes: true # Deploy one webhook per node
autoscaling:
enabled: false # Disable autoscaling when using allNodes
Persistence in Queue Mode
Persistence: Configure persistent storage for main and worker nodes independently. Persistence is used to store workflows, configuration, and npm packages. Configure independently from hostAliases.
Main Node Persistence Example
main:
count: 1
persistence:
enabled: true
volumeName: "n8n-main-data"
mountPath: "/home/node/.n8n"
size: 8Gi
accessMode: ReadWriteOnce
storageClass: "fast-ssd"
annotations:
helm.sh/resource-policy: keep
Worker Node Persistence Example
worker:
mode: queue
count: 3
persistence:
enabled: true
volumeName: "n8n-worker-data"
mountPath: "/home/node/.n8n"
size: 5Gi
accessMode: ReadWriteOnce
Autoscaling Limitations: Worker nodes with ReadWriteOnce
persistence cannot use autoscaling. Use ReadWriteMany
for autoscaling or ReadWriteOnce
with StatefulSets for fixed scaling.
Worker Persistence with Autoscaling
worker:
mode: queue
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
persistence:
enabled: true
volumeName: "n8n-worker-data"
mountPath: "/home/node/.n8n"
size: 5Gi
accessMode: ReadWriteMany # For autoscaling
storageClass: "fast-ssd"
Worker Persistence with StatefulSet
worker:
mode: queue
count: 3
persistence:
enabled: true
mountPath: "/home/node/.n8n"
size: 5Gi
accessMode: ReadWriteOnce
Automatic StatefulSet: When persistence is enabled with ReadWriteOnce
access mode, the chart automatically deploys worker nodes as StatefulSets. Each pod gets its own persistent volume with a unique name.
Resource Management
Pod Affinity and Anti-Affinity
Advanced Scheduling: Use affinity rules to control pod placement and optimize resource utilization in queue mode deployments.
Deprecation Notice: The top-level affinity
field is deprecated. Use the specific affinity configurations under main
, worker
, and webhook
blocks instead.
Spread Worker Pods Across Nodes
worker:
mode: queue
count: 3
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/name: n8n
app.kubernetes.io/component: worker
topologyKey: kubernetes.io/hostname
Spread Webhook Pods Across Zones
webhook:
mode: queue
url: "https://webhook.yourdomain.com"
count: 2
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: n8n
app.kubernetes.io/component: webhook
topologyKey: topology.kubernetes.io/zone
Co-locate Main and Worker Pods
main:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: n8n
topologyKey: kubernetes.io/hostname
worker:
mode: queue
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: n8n
app.kubernetes.io/component: main
topologyKey: kubernetes.io/hostname
Node Affinity for Specific Node Types
worker:
mode: queue
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- compute-optimized
- key: kubernetes.io/os
operator: In
values:
- linux
webhook:
mode: queue
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: node-role.kubernetes.io/worker
operator: Exists
Affinity Benefits: Proper affinity configuration improves availability, resource utilization, and performance in queue mode deployments.
External Redis Configuration
# Disable built-in Redis
redis:
enabled: false
# Configure external Redis
externalRedis:
host: your-redis-host.com
port: 6379
username: default
password: your-redis-password
existingSecret: redis-secret # Use Kubernetes secret
High Availability Redis
redis:
enabled: true
architecture: replication # Master-slave replication
master:
persistence:
enabled: true
size: 10Gi
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
replica:
replicaCount: 2
persistence:
enabled: true
size: 10Gi
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
Production Queue Mode Examples
Small Production Setup
# Small production (2-5 users)
db:
type: postgresdb
postgresql:
enabled: true
auth:
username: n8n
password: your-secure-password
database: n8n
primary:
persistence:
enabled: true
size: 20Gi
redis:
enabled: true
architecture: standalone
master:
persistence:
enabled: true
size: 10Gi
worker:
mode: queue
count: 3
concurrency: 10
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
webhook:
mode: queue
url: "https://webhook.yourdomain.com"
count: 2
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 512m
memory: 512Mi
ingress:
enabled: true
hosts:
- host: n8n.yourdomain.com
paths:
- path: /
pathType: Prefix
Medium Production Setup
# Medium production (5-20 users)
db:
type: postgresdb
postgresql:
enabled: true
auth:
username: n8n
password: your-secure-password
database: n8n
primary:
persistence:
enabled: true
size: 50Gi
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
redis:
enabled: true
architecture: replication
master:
persistence:
enabled: true
size: 20Gi
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
replica:
replicaCount: 2
persistence:
enabled: true
size: 20Gi
worker:
mode: queue
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 15
metrics:
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
resources:
requests:
cpu: 1000m
memory: 1Gi
limits:
cpu: 4000m
memory: 4Gi
webhook:
mode: queue
url: "https://webhook.yourdomain.com"
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi
ingress:
enabled: true
hosts:
- host: n8n.yourdomain.com
paths:
- path: /
pathType: Prefix
Large Production Setup
# Large production (20+ users)
db:
type: postgresdb
externalPostgresql:
host: your-postgres-host.com
port: 5432
username: n8n
password: your-secure-password
database: n8n
existingSecret: postgres-secret
externalRedis:
host: your-redis-host.com
port: 6379
password: your-redis-password
existingSecret: redis-secret
worker:
mode: queue
autoscaling:
enabled: true
minReplicas: 5
maxReplicas: 50
metrics:
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: executions-per-second
target:
type: AverageValue
averageValue: 100
resources:
requests:
cpu: 2000m
memory: 2Gi
limits:
cpu: 8000m
memory: 8Gi
webhook:
mode: queue
url: "https://webhook.yourdomain.com"
autoscaling:
enabled: true
minReplicas: 5
maxReplicas: 20
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
ingress:
enabled: true
hosts:
- host: n8n.yourdomain.com
paths:
- path: /
pathType: Prefix
Monitoring and Observability
ServiceMonitor Configuration
serviceMonitor:
enabled: true
interval: 30s
timeout: 10s
labels:
release: prometheus
include:
defaultMetrics: true
cacheMetrics: true
messageEventBusMetrics: true
queueMetrics: true
workflowIdLabel: true
nodeTypeLabel: true
Logging Configuration
log:
level: info
output:
- console
scopes:
- concurrency
- pubsub
- redis
- scaling
- waiting-executions
Health Checks
main:
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz/readiness
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
worker:
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz/readiness
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
webhook:
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz/readiness
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
Troubleshooting
Common Issues
Redis Connection Issues
# Check Redis pod status
kubectl get pods -l app.kubernetes.io/name=redis
# Check Redis logs
kubectl logs -l app.kubernetes.io/name=redis
# Test Redis connection
kubectl exec -it <redis-pod> -- redis-cli ping
Worker Node Issues
# Check worker pod status
kubectl get pods -l app.kubernetes.io/component=worker
# Check worker logs
kubectl logs -l app.kubernetes.io/component=worker
# Check worker metrics
kubectl top pods -l app.kubernetes.io/component=worker
Webhook Node Issues
# Check webhook pod status
kubectl get pods -l app.kubernetes.io/component=webhook
# Check webhook logs
kubectl logs -l app.kubernetes.io/component=webhook
# Test webhook endpoint
curl -X POST https://webhook.yourdomain.com/webhook-test/18ca0dba-fd0f-415a-abb5-8fb65d10653b/webhook
Performance Optimization
Worker Concurrency Tuning
worker:
mode: queue
concurrency: 5 # Start with lower value, increase based on performance
resources:
requests:
cpu: 1000m
memory: 1Gi
limits:
cpu: 4000m
memory: 4Gi
Redis Performance
redis:
enabled: true
architecture: replication
master:
persistence:
enabled: true
size: 20Gi
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 2Gi
configuration: |
maxmemory 1gb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
Database Performance
db:
type: postgresdb
logging:
enabled: true
options: error
maxQueryExecutionTime: 1000
postgresql:
enabled: true
primary:
configuration: |
shared_buffers = 256MB
effective_cache_size = 1GB
maintenance_work_mem = 64MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
work_mem = 4MB
min_wal_size = 1GB
max_wal_size = 4GB
Best Practices
Scaling
- Start with 2-3 worker nodes and scale based on demand
- Use autoscaling for variable workloads
- Monitor CPU and memory usage for scaling decisions
- Consider deploying workers on all nodes for high availability
Performance
- Use PostgreSQL for production workloads
- Configure appropriate Redis memory limits
- Monitor queue depths and processing times
- Tune worker concurrency based on workload
Reliability
- Use Redis replication for high availability
- Configure proper health checks and probes
- Set up monitoring and alerting
- Use persistent storage for databases and Redis
Security
- Use Kubernetes secrets for sensitive data
- Enable network policies to restrict communication
- Use HTTPS for webhook endpoints
- Regularly update Redis and PostgreSQL versions
Next Steps
- Usage Guide - Quick start and basic deployment
- Configuration Guide - Detailed configuration options
- Database Setup - PostgreSQL and external database configuration
- Storage Configuration - Binary data storage options
- Monitoring Setup - Metrics and observability
- Troubleshooting - Common issues and solutions