Production Hardware Sizing for n8n: Compute, Memory, and PostgreSQL Tuning at Scale
Deploying n8n without calculated hardware allocations leads to sudden pipeline halts under load. Because n8n’s primary engine runs on single-threaded Node.js event loops while workers offload workloads asynchronously, infrastructure bottlenecks rarely occur uniformly. A cluster can exhaust all available PostgreSQL connection pools while maintaining low overall CPU utilization, or crash unexpectedly due to Linux Out-Of-Memory (OOM) reaper events triggered by large payload parsing.
Accurately dimensioning compute, memory, and database configurations prevents over-provisioning cloud budgets while securing stability up to tens of millions of monthly executions.
Prerequisite: Sizing recommendations below assume deployment in distributed Queue Mode. If your cluster is still running as a single container, review our guide on Deploying n8n in Queue Mode with Docker Compose and configure Prometheus Telemetryto measure consumption in real time.
Hardware Sizing Matrix by Monthly Volume
The following hardware baselines reflect production clusters operating with execution pruning (EXECUTIONS_DATA_PRUNE=true) enabled:
| Monthly Task / Execution Volume | Recommended Node Topology | Dedicated Compute (vCPU / RAM) | Storage Spec (NVMe) | Estimated Cloud Cost |
| Tier 1: Up to 250,000 | 1 Monolithic Node (Internal Postgres/Redis) | 2 vCPU / 4 GB RAM | 40 GB NVMe | ~$10 – $20 / mo |
| Tier 2: 250,000 – 2,000,000 | 1 Primary Engine + 2 Workers + Shared DB | 4 vCPU / 8 GB RAM | 80 GB NVMe | ~$40 – $70 / mo |
| Tier 3: 2,000,000 – 10,000,000 | 1 Ingress + 4–8 Scaled Workers + Dedicated DB | 8–16 vCPU / 16–32 GB RAM | 200 GB NVMe (High IOPS) | ~$120 – $250 / mo |
| Tier 4: 10,000,000+ | Multi-node Kubernetes or Distributed VPS | Horizontal Auto-scaling | Managed Managed DB Cluster | Custom ($400+/mo) |
Memory Dimensioning: The Node.js Payload Factor
A common pitfall is calculating RAM based strictly on concurrency. In Node.js runtimes, memory usage spikes proportionally to JSON payload size:
$$\text{Memory Overhead per Task} \approx \text{Raw Payload Size} \times 4.5$$
When an n8n node parses a 15 MB raw CSV or deeply nested JSON array, V8 memory allocation can easily peak at 70 MB to 100 MB per worker process during object deserialization.
To protect against memory fragmentation and fatal container reboots:
- Set Hard Docker Container Ceilings: Never run workers without limits.
deploy:
resources:
limits:
memory: 2048M
cpus: '2.0'
2. Configure the V8 Heap Allocation: Define the memory flag in your container environment:
NODE_OPTIONS=--max-old-space-size=1536
PostgreSQL Database Tuning for High-Concurrency n8n
The default PostgreSQL configuration is optimized for minimal resource footprints, not high-volume concurrent pipeline execution. Heavy write rates against execution_entity tables will exhaust connection buffers without proper tuning.
Apply these tuned values to your /etc/postgresql/postgresql.conf or Docker DB initialization parameters:
# Memory Configuration for an 8 GB RAM Dedicated Database Node
shared_buffers = 2GB # 25% of total system memory
effective_cache_size = 6GB # 75% of total system memory
maintenance_work_mem = 512MB
work_mem = 32MB # Allocates memory per sorting operation
# Write-Ahead Log (WAL) & Checkpoint Tuning
wal_buffers = 16MB
checkpoint_completion_target = 0.9
max_wal_size = 4GB
min_wal_size = 1GB
# Connection Pool Settings
max_connections = 150 # Avoid setting excessively high without PgBouncer
Table Pruning Strategy
Without automated pruning, PostgreSQL table indexes will fragment, causing workflow execution lookup latency to climb exponentially. Maintain these environment variables on your primary n8n instance:
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=168 # Retain executions for 7 days (in hours)
EXECUTIONS_DATA_PRUNE_MAX_COUNT=50000 # Retain last 50k executions maximum
air this with an offsite archival pipeline using our Automated Encrypted Backups to S3 Blueprint to ensure data longevity.
Redis Memory Allocation for BullQueues
Redis operates purely in-memory. For n8n Queue Mode, Redis stores job metadata, payload pointers, and queue states.
For 99% of deployments, 1 GB to 2 GB of RAM is sufficient for Redis, provided that workflow outputs are not stored permanently inside the queue.
Key Redis configuration (redis.conf):
maxmemory 1500mb
maxmemory-policy noeviction
save "" # Disable RDB snapshots if Redis is strictly used as an ephemeral queue
appendonly no # Turn off AOF for pure in-memory queue throughput
Note: Using maxmemory-policy noeviction ensures that Redis returns an error rather than silently evicting active BullQueue job IDs if capacity is reached.
Frequently Asked Questions
Can I run n8n on ARM-based cloud servers (e.g., AWS Graviton, Ampere)?
Yes. Modern n8n Docker images provide multi-arch builds (linux/amd64 and linux/arm64). Running on ARM instances often yields a 20–30% cost-performance improvement on AWS and Oracle Cloud.
Why do worker containers experience OOMKilled status during batch transforms?
When processing large arrays, operations like .map() or .filter() duplicate data arrays in memory. If the container limit is reached, the kernel immediately terminates the process with exit code 137. Scale container memory limits or stream payloads via disk rather than holding them entirely in memory.