Who this is for: DevOps engineers and n8n power‑users running production‑grade workflows who see latency spikes while the host CPU stays under 20 %. We cover this in detail in the n8n Performance Degradation & Stability Issues Guide.
Quick Fixes
| Step | Action |
|---|---|
| 1. | Enable DB query logging; hunt for > 100 ms queries. |
| 2. | Switch executionMode to queue (or worker) in ~/.n8n/config. |
| 3. | Insert a Delay node or lower batch size for long loops. |
| 4. | Restart n8n and verify node latency drops below 200 ms. |
If latency remains high, follow the detailed troubleshooting checklist below.
1. Common Non‑CPU Causes of n8n Slowdowns
If you encounter any n8n workflows slow after weeks in production root cause analysis resolve them before continuing with the setup.
| Symptom | Likely Root Cause | Quick Check |
|---|---|---|
| Requests take 2‑5 s but CPU < 10 % | PostgreSQL/SQLite query latency | SELECT * FROM pg_stat_activity WHERE state='active'; |
| Workflow stalls after a specific node | Blocking external API (rate‑limit, high latency) | curl -w "%{time_total}" <api‑url> |
| Memory climbs slowly, CPU flat | Memory leak in custom node / large payload | docker stats → RSS growth |
| All workflows become sluggish simultaneously | Redis queue saturation or exhausted worker pool | redis-cli INFO stats → instantaneous_ops_per_sec |
| Intermittent spikes only on start‑up | Cold‑start of Docker containers / missing caches | Check container logs for “Pulling image” messages |
EEFA note: In production, always run n8n with a dedicated PostgreSQL instance (not SQLite) and use Redis for the queue. SQLite with high concurrency is a frequent hidden cause of “low‑CPU” slowdowns.
2. Step‑by‑Step Troubleshooting Workflow
2.1 Capture Baseline Metrics
Purpose: Record current performance numbers so you can measure the impact of each change.
# Run a lightweight Prometheus node‑exporter alongside n8n docker run -d --name n8n-metrics \ -p 9100:9100 \ -v /var/run/docker.sock:/var/run/docker.sock \ prom/node-exporter
| Metric | Expected (healthy) | Alarm Threshold |
|---|---|---|
| process_cpu_seconds_total | < 0.2 s per request | > 0.5 s |
| process_resident_memory_bytes | < 300 MiB per instance | > 500 MiB |
| n8n_workflow_execution_time_seconds | < 0.3 s per node | > 1 s |
Record these values before any modifications. If you encounter any why n8n execution time increases over time resolve them before continuing with the setup.
2.2 Enable Detailed DB Logging
PostgreSQL – Log any query that exceeds 50 ms:
ALTER SYSTEM SET log_min_duration_statement = 50; SELECT pg_reload_conf();
SQLite (if you must use it) – Turn on tracing via an environment variable:
export SQLITE_TRACE=1 n8n start
After a few minutes, scan the logs for queries consistently over 50 ms. Those are prime candidates for indexing or rewriting.
2.3 Switch Execution Mode to Queue / Worker
Running in the default main mode executes everything in a single process, which can block on I/O. Move to a queue‑based architecture:
// ~/.n8n/config
{
"executionMode": "queue",
"queue": {
"type": "redis",
"host": "redis.mycompany.internal",
"port": 6379,
"password": "••••••"
}
}
Restart the container to apply the new configuration:
docker restart n8n
EEFA warning: When using queue mode, enable Redis persistence (
appendonly yes) to avoid lost executions during power loss.
2.4 Profile Individual Workflows
- Open the workflow in the UI.
- Click Execution → Debug and enable “Show execution time per node.”
- Run the workflow with a typical payload.
Identify nodes whose Duration exceeds 300 ms and apply the fixes listed in the table below.
| Node Type | Typical Fix |
|---|---|
| HTTP Request | Add timeout: 5000 and enable Retry with exponential back‑off |
| Function / Code | Move heavy loops to a Run Once node or external micro‑service |
| SplitInBatches | Reduce batchSize (e.g., 100 → 20) and insert a Delay node between batches |
| Set / Merge | Trim payload size; store large blobs in external storage (S3) instead of workflow context |
2.5 Optimize Repeated External Calls
Add a Redis‑backed cache so identical HTTP requests within a short window hit memory instead of the remote service:
# n8n-config.yml cache: type: redis ttl: 300 # seconds host: redis.mycompany.internal
Now a repeat request within five minutes is served from cache, shaving 150‑300 ms off each execution.
3. Checklist – “Low‑CPU but Slow” Debug Session
- Capture baseline Prometheus metrics.
- Enable DB query logging (
log_min_duration_statement = 50). - Identify > 50 ms queries → add indexes or rewrite.
- Switch
executionModeto queue (Redis). - Verify Redis health (
redis-cli INFO replication). - Run workflow in Debug mode → note slow nodes.
- Add timeouts / retries to HTTP nodes.
- Reduce batch sizes or add Delay nodes.
- Enable n8n cache for repeatable external calls.
- Restart n8n, re‑measure latency.
Iterate on any remaining red items until all checks pass. If you encounter any n8n uses more memory every day leak or design issue resolve them before continuing with the setup.
4. Real‑World Production Tips (EEFA)
| Situation | Recommended Fix | Why It Works |
|---|---|---|
| Burst traffic spikes (e.g., webhook surge) | Deploy multiple worker containers behind a load balancer; raise workerConcurrency to 10‑20. |
Workers run in parallel, preventing a single‑process queue from becoming a bottleneck. |
| Large payloads (>5 MiB) | Store data in S3/MinIO; pass only the URL in the workflow. | Keeps the n8n process memory‑light; avoids garbage‑collection pauses that mimic CPU throttling. |
| Frequent “Connection reset by peer” from external APIs | Add a Circuit Breaker community node with a 30‑second cool‑down. | Stops repeated failing calls that fill the event loop and cause apparent slowness. |
| Running on a shared VPS | Pin n8n’s Docker container to a dedicated CPU core (--cpuset-cpus="2"). |
Guarantees background OS tasks don’t starve the Node.js event loop, even when CPU looks low. |
Bottom Line
Low CPU utilization does not guarantee a healthy n8n instance. By systematically:
- Profiling the database,
- Switching to a queue‑based execution model,
- Tightening workflow design (batch size, timeouts, caching),
you eliminate hidden bottlenecks that cause “slow but idle” behavior. Follow the checklist, monitor the metrics, and you’ll consistently achieve sub‑second response times without over‑provisioning CPU resources.



