Who this is for: Engineers running production‑grade n8n automations who need predictable costs and reliable performance. We cover this in detail in the n8n Cost, Scaling & Infrastructure Economics Guide.
Quick Diagnosis
n8n’s cost surge at scale is driven by five core factors:
- Unlimited worker concurrency – spawns too many Node.js workers.
- High‑frequency polling & webhook traffic – wastes API calls.
- Inefficient data handling – large payloads and redundant logs.
- Storage & DB I/O pressure – bloated PostgreSQL tables.
- Default container‑orchestration settings – over‑provisioned VMs.
Often the bill rises after a few dozen workflows, not on day one.
Mitigation cheat‑sheet
| Action | Quick setting |
|---|---|
| Cap workers | WORKER_CONCURRENCY=5 |
| Switch to events | Replace Cron/Poll with Webhook |
| Trim logs & offload binaries | EXECUTIONS_DATA_SAVE_MAX_DAYS=7 + S3 storage |
| Right‑size DB | max_connections=200, use PgBouncer |
| Tune orchestration | Deploy 3‑replica K8s pod, enable HPA |
A tuned stack can keep per‑workflow cost under $0.02 even at 10 k executions / day.
Is Your n8n Bill Growing Unexpectedly?
If you encounter any cost of retries in n8n resolve them before continuing with the setup.
| Symptom | Likely Root Cause | Immediate Fix |
|---|---|---|
| Monthly cloud bill ↑ 3× after adding 2 workflows | Unlimited worker concurrency → CPU spikes | Set WORKER_CONCURRENCY=5 in .env |
| API‑rate‑limit errors & extra third‑party charges | High‑frequency polling triggers | Replace Cron with Webhook or event bridge |
| DB storage > 80 GB, backup cost exploding | Large payloads stored in execution logs | Set EXECUTIONS_DATA_SAVE_MAX_DAYS=7 & enable external binary storage |
| CPU usage > 90 % on a single node | No horizontal scaling | Deploy n8n as a Kubernetes Deployment with replicas: 3 |
If a row matches, you’re probably in the classic “cost explosion” pattern.
1. Concurrency & Worker Management
Why unlimited concurrency is expensive – Each incoming webhook spawns a new Node.js worker, causing CPU contention, memory bloat, and forced upgrades to larger cloud instances. If you encounter any redis vs sqs cost comparison n8n resolve them before continuing with the setup.
Step‑by‑step: Cap concurrency
- Add the limit to your environment file
# Limit to 5 concurrent workers (adjust per core count) WORKER_CONCURRENCY=5 EXECUTIONS_PROCESS=queue # optional queue fallback
The setting lives in the same
.envyou use for other n8n options, so you can edit it alongside the DB credentials. - Restart the service
# Docker docker-compose up -d --force-recreate n8n # Kubernetes kubectl rollout restart deployment n8n
- Watch the metrics and verify CPU stays under 70 % via Prometheus or the built‑in
/metricsendpoint.
Usually, matching concurrency to core count balances throughput and cost.
2. Trigger Types – Polling vs. Event‑Driven
The hidden cost of polling – Polling nodes hit external APIs on a fixed schedule, even when nothing has changed. At scale this generates unnecessary API fees and extra compute. If you encounter any db cost optimization high volume workflows resolve them before continuing with the setup.
It’s easy to forget that a poll node keeps hitting the API even when nothing changed – we often see this after a weekend of adding a new integration.
Cost per typical poll trigger
| Trigger | Calls / hour (default) | Typical API price | Approx. monthly impact |
|---|---|---|---|
| Cron (every 5 min) | 12 | $0.001 per call | $0.72 per workflow |
| Google Sheets – List Rows | 12 | $0.02 per 1 k rows | $1.44 per workflow |
| Generic HTTP poll | 12 | Varies | Unpredictable |
Multiply by dozens of workflows → hundreds of dollars in third‑party fees.
Migration checklist: Polling → Webhook
| Action | Details |
|---|---|
| Identify poll nodes | Filter execution logs: trigger.type = poll |
| Add a Webhook node | Expose /webhook/:id endpoint |
| Configure source to push events | E.g., GitHub → Repository Dispatch |
| Add retry/back‑off | Use an “Error Trigger” with exponential back‑off |
| Remove old poll nodes | Disable or delete to stop stray executions |
Example webhook payload (JSON)
{
"event": "order.created",
"data": {
"orderId": "{{ $json.id }}",
"total": "{{ $json.amount }}"
}
}
EEFA Warning – Some SaaS providers charge per inbound webhook; verify before switching.
3. Data Handling – Payload Size & Execution Logging
Execution log bloat
n8n stores every node’s input/output for 30 days by default (EXECUTIONS_DATA_SAVE_MAX_DAYS=30). Large blobs (PDFs, images) can double DB size daily.
Storage cost illustration (PostgreSQL on AWS RDS)
| Daily avg. payload | DB growth / day | RDS storage cost (US‑East‑1) |
|---|---|---|
| 5 MB | 150 MB | $0.10 |
| 20 MB | 600 MB | $0.40 |
| 50 MB | 1.5 GB | $1.00 |
Those numbers assume you keep the default 30‑day retention; cutting it down has a direct impact on the growth curve.
Reduce log volume
- Strip unnecessary fields before logging – add a “Set” node after each API call:
// Remove large binary fields before they hit the DB delete $json.file; delete $json.imageBase64;
- Shorten retention in
.envEXECUTIONS_DATA_SAVE_MAX_DAYS=7 # keep only a week EXECUTIONS_DATA_MAX_SIZE=5mb # discard >5 MB payloads
- Offload binaries to object storage (S3, GCS) and keep only references in the DB
# n8n config for S3 binary storage BINARY_DATA_STORAGE: s3 S3_BUCKET: n8n-binaries
Moving large files to S3 improves efficiency (DB I/O) and affordability (pay‑as‑you‑go storage).
4. Database & Queue Layer – Scaling the Backend
When the DB becomes the bottleneck
- Lock contention on
execution_entitytables. - Slow look‑ups for
SELECT * FROM execution_entity WHERE id = $1.
Optimized stack
| Layer | Recommended setting | Why it helps |
|---|---|---|
| PostgreSQL | max_connections = 200 shared_buffers = 25 % RAM |
Handles bursts of parallel reads/writes |
| Redis (queue) | maxmemory-policy allkeys-lru | Evicts old items before OOM |
| n8n workers | EXECUTIONS_PROCESS=queue | Decouples HTTP handling from execution |
Kubernetes deployment (split into two focused snippets)
Deployment skeleton – defines replicas and pod template:
apiVersion: apps/v1
kind: Deployment
metadata:
name: n8n
spec:
replicas: 3
selector:
matchLabels:
app: n8n
template:
metadata:
labels:
app: n8n
Container specs – n8n app and Redis sidecar with resource limits:
spec:
containers:
- name: n8n
image: n8nio/n8n:latest
envFrom:
- configMapRef:
name: n8n-env
resources:
limits:
cpu: "500m"
memory: "512Mi"
- name: redis
image: redis:6-alpine
resources:
limits:
cpu: "200m"
memory: "256Mi"
Most teams find PgBouncer essential once they hit a few hundred concurrent executions.
EEFA Tip – Enable Horizontal Pod Autoscaling (
cpu > 70 %) to keep Fault‑tolerance proportional to load while controlling cost.
5. Cloud Provider & Hosting Model – Choosing the Right Tier
| Model | Base cost (USD/mo) | Scaling approach | Hidden cost drivers |
|---|---|---|---|
| n8n.cloud (Standard) | $20 | Auto‑scale compute & DB | Third‑party API overage |
| Self‑hosted on EC2 | $35 (t3.medium) | Manual scaling | EBS storage, data transfer, backup |
| Self‑hosted on EKS | $70 (2 nodes) | Pod autoscaling | Control‑plane fees, ALB traffic |
When you first spin up n8n.cloud the flat fee looks cheap, but hidden API overages can double the bill in a month.
Cost‑control checklist for self‑hosted stacks
- Spot instances for worker nodes – up to 80 % savings.
- EBS lifecycle policies – auto‑delete volumes after 30 days.
- CloudWatch alarms – stop idle instances when CPU < 10 % for 2 h.
- Reserved DB instances – lock in lower rates if utilization > 70 %.
EEFA Advisory – Spot termination can interrupt workflows; pair with a Redis‑based retry queue to preserve Fault‑tolerance.
6. Monitoring & Alerting – Prevent Future Explosions
| Metric | Ideal threshold | Alert action |
|---|---|---|
| n8n_worker_cpu_percent | < 70 % | Scale up replicas |
| n8n_queue_length | < 100 | Increase WORKER_CONCURRENCY |
| db_query_latency_ms | < 150 | Optimize indexes |
| s3_storage_bytes | < 10 GB | Review binary cleanup rules |
Prometheus rule – high CPU on workers
- alert: N8NHighWorkerCPU
expr: avg by (instance) (rate(process_cpu_seconds_total[5m])) > 0.7
for: 2m
labels:
severity: warning
annotations:
summary: "High CPU on n8n worker {{ $labels.instance }}"
description: "CPU usage > 70 % for 2 min. Consider increasing replica count."
Prometheus scrapes the /metrics endpoint that n8n exposes out of the box.
7. Real‑World Production Checklist – Keep Costs Predictable
- Cap worker concurrency (
WORKER_CONCURRENCY). - Migrate high‑frequency polls to webhooks.
- Trim execution logs & offload binaries (
EXECUTIONS_DATA_MAX_SIZE). - Deploy with a queue backend (Redis) and enable
EXECUTIONS_PROCESS=queue. - Right‑size PostgreSQL & enable connection pooling (PgBouncer).
- Implement auto‑scaling policies (K8s HPA or cloud auto‑scale groups).
- Set up cost‑monitoring alerts (Prometheus, CloudWatch).
- Review third‑party API usage monthly for hidden fees.
Conclusion
n8n’s cost explosion is rarely a mystery – it’s the result of unbounded concurrency, wasteful polling, and unchecked data growth. By capping workers, moving to event‑driven triggers, trimming logs, right‑sizing the database, and tuning orchestration resources, you can keep per‑workflow spend under a few cents even at high volume. Apply the checklist, monitor the key metrics, and your automation platform will stay both affordable and reliable in production.



