Who this is for: Operators of self‑hosted n8n (Docker, Kubernetes, or bare‑metal) who need reliable control over workflow parallelism in production. We cover this in detail in the n8n Performance & Scaling Guide.
Quick Diagnosis
Set the environment variable N8N_MAX_EXECUTIONS_CONCURRENT (or the maxConcurrentExecutions key in config.yml) and restart n8n. Verify the new cap with n8n status. If you encounter any error handling optimizations resolve them before continuing with the setup.
docker run -d \ -e N8N_MAX_EXECUTIONS_CONCURRENT=20 \ -e EXECUTIONS_PROCESS=queue \ --name n8n n8nio/n8n
1. Why Concurrency Limits Matter in n8n ?
If you encounter any fallback and retry strategies resolve them before continuing with the setup.
| Symptom | Root Cause | Production Impact |
|---|---|---|
| “Too many concurrent executions” | No cap on parallel runs | CPU/memory thrash, API rate‑limit hits |
| Stalled jobs in the queue | Queue overflow | Latency, missed SLAs |
| Unexpected container restarts | OOM killer triggered | Downtime, state loss (if not persisted) |
| High webhook latency | All workers busy | Poor UX, webhook timeouts |
n8n spawns a separate Node.js worker per workflow execution. Without a ceiling the worker pool can explode, especially under bursty webhook traffic. Concurrency limits give deterministic resource usage and protect downstream services.
2. Core Configuration Options
2.1 Keys, defaults, and environment variables
| Config key / Env var | Default |
|---|---|
| maxConcurrentExecutions / N8N_MAX_EXECUTIONS_CONCURRENT | 5 (in‑memory) |
| executionTimeout / EXECUTIONS_TIMEOUT | 3600 s |
| queueMode / QUEUE_MODE | memory |
| queueBullRedisHost / QUEUE_BULL_REDIS_HOST | localhost |
| workerCount / EXECUTIONS_PROCESS | main |
2.2 Accepted ranges and typical production values
| Setting | Accepted values | Typical production setting |
|---|---|---|
| maxConcurrentExecutions | 1‑1000 (hardware‑dependent) | 20‑50 for 4‑CPU, 8 GB RAM |
| executionTimeout | seconds (0 = unlimited) | 300 s for fast APIs |
| queueMode | memory, bull | bull when Redis is available |
| workerCount (EXECUTIONS_PROCESS) | main, queue | queue for large scale |
| Redis host (QUEUE_BULL_REDIS_HOST) | hostname/IP | Redis cluster endpoint |
EEFA note: Raising maxConcurrentExecutions above the number of CPU cores does not linearly increase throughput; each worker is single‑threaded. Balance CPU, memory, and downstream API rate limits. If you encounter any webhook throughput resolve them before continuing with the setup.
3. Step‑by‑Step: Configuring Concurrency in Different Deployments
3.1 Docker Compose (most common self‑hosted)
Deploy file (excerpt) – keep the concurrency settings together.
services:
n8n:
image: n8nio/n8n
restart: unless-stopped
environment:
- N8N_HOST=example.com
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=strongpassword
# Concurrency settings
- N8N_MAX_EXECUTIONS_CONCURRENT=30
- EXECUTIONS_PROCESS=queue
- QUEUE_BULL_REDIS_HOST=redis
ports:
- "5678:5678"
depends_on:
- redis
Post‑deployment checklist
| Item | Command |
|---|---|
| Verify env var | docker exec n8n printenv | grep N8N_MAX_EXECUTIONS_CONCURRENT |
| Confirm queue mode | docker logs n8n | grep “Queue mode: bull” |
| Load‑test sanity | Run 50 parallel webhook calls; monitor with docker stats n8n |
3.2 Kubernetes (Helm chart)
values.yaml excerpt – focus on concurrency and resources.
env:
- name: N8N_MAX_EXECUTIONS_CONCURRENT
value: "40"
- name: EXECUTIONS_PROCESS
value: "queue"
- name: QUEUE_BULL_REDIS_HOST
value: "redis-master.redis.svc.cluster.local"
resources:
limits:
cpu: "4"
memory: "8Gi"
requests:
cpu: "2"
memory: "4Gi"
Validate the rollout
kubectl rollout status deployment/n8n
kubectl exec -it $(kubectl get pod -l app=n8n -o jsonpath="{.items[0].metadata.name}") \
-- printenv N8N_MAX_EXECUTIONS_CONCURRENT
3.3 Bare‑metal / Systemd Service
Create /etc/n8n/config.yml – minimal but complete.
maxConcurrentExecutions: 25 executionTimeout: 300 queueMode: bull queueBullRedisHost: 127.0.0.1
Reload and restart the service
sudo systemctl daemon-reload
sudo systemctl restart n8n
4. Monitoring & Troubleshooting Concurrency Issues
| Symptom | Diagnostic command | Expected output | Fix |
|---|---|---|---|
| “Queue full” errors | docker logs n8n | grep “queue” | Queue size: 1500 (max 1000) | Raise maxConcurrentExecutions or add pods |
| Workers stuck on a step | ps -ef | grep node | grep n8n | Many node processes with identical PIDs | Add executionTimeout |
| High memory per worker | docker stats n8n –format “{{.MemPerc}}” | > 80 % per worker | Lower concurrency or increase container memory |
| Downstream API rate‑limit | Inspect downstream logs (e.g., Stripe) | 429 responses | Reduce concurrency and add rate‑limit nodes |
EEFA tip: With Bull, inspect Redis keys to see queue pressure.
redis-cli --scan --pattern "bull:n8n:*" | while read key; do echo "$key -> $(redis-cli get $key)" done
A surge in bull:n8n:wait indicates the concurrency cap is being hit.
5. Advanced Patterns – Dynamic Concurrency Scaling
5.1 Auto‑scale workers with Kubernetes HPA
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: n8n-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: n8n
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: n8n_queue_length
target:
type: AverageValue
averageValue: "200"
Expose n8n_queue_length via Prometheus to drive scaling.
5.2 Per‑workflow concurrency limits
From n8n v0.200, the **Execute Workflow** node accepts maxConcurrentRuns.
{
"name": "Execute Workflow",
"type": "n8n-nodes-base.executeWorkflow",
"parameters": {
"workflowId": "123",
"maxConcurrentRuns": 3
}
}
This prevents a single heavy workflow from starving others.
5.3 Graceful degradation
Combine a circuit‑breaker node (or external Hystrix‑style service) with a low maxConcurrentExecutions. When the limit is reached, route new webhook payloads to a dead‑letter queue for later retry.
Conclusion
Setting a sensible maxConcurrentExecutions value aligns n8n’s worker pool with your hardware, API rate limits, and SLA requirements. Monitor queue depth and memory usage, and adjust the limit or scale workers before the system reaches OOM or downstream throttling. By coupling static caps with dynamic patterns such as HPA and per‑workflow limits, you achieve predictable throughput while protecting both n8n and the services it orchestrates.



