### Part 1: The Real-World Pain / Symptom
You push a heavy sub-workflow fan-out—say, 10,000+ items processed concurrently—expecting the execution pipeline to clear in a few minutes. Instead, your n8n UI execution history shows workflows stuck in a perpetual ‘Running’ state for up to 24 hours.
Yet, when you check individual node logs, the processing time per item is actually blazing fast (around 200ms). Your CPU and RAM are under-utilized, but your self-hosted n8n instance feels entirely unresponsive. Jobs pile up, webhooks time out, and your monitoring alerts start screaming.
Part 2: The Architectural Root Cause
The bottleneck isn’t your logic, and it isn’t your CPU. It’s **PostgreSQL write contention and bloated execution state persistence**.
By default, self-hosted n8n writes every single execution state, node input, and node output directly into your PostgreSQL database (`execution_entity` table). When you fan out 10,000 items concurrently, n8n attempts thousands of simultaneous write operations and index updates on the database.
PostgreSQL quickly bogs down in lock contention, connection pool exhaustion, and WAL (Write-Ahead Log) flushing limits. The execution thread is blocked waiting for database write acknowledgments, causing the UI and execution queue to freeze while the database struggles to clear its write queue.
Part 3: The 3-Step Architectural Fix
To handle high-volume fan-out without choking your database, you must decouple data persistence from execution speed and control concurrency.
- **Implement Chunking and Batching via the Loop Node**
- Never dump 10,000 items into a parallel sub-workflow simultaneously.
- Insert a **Loop Node** or **Split In Batches** node upstream. Process your payload in controlled batches (e.g., chunks of 100 to 250 items).
- Add a microscopic `Wait` node (e.g., 50ms–100ms) between batches to allow the database I/O queue to drain.
- **Tune PostgreSQL for High-Throughput Write Operations**
- Your default `postgresql.conf` is optimized for general web apps, not high-frequency event streaming. Adjust these parameters in your container/server setup:
- Increase `shared_buffers` (typically 25% of total RAM).
- Increase `effective_cache_size` (50% to 75% of total RAM).
- Tune `wal_buffers` and set `checkpoint_completion_target = 0.9` to smooth out disk write spikes.
- Ensure your database is running on fast NVMe storage with high IOPS.
- **Aggressively Prune Execution History Data**
- Stop keeping execution logs forever. Set environment variables in your n8n deployment to automatically purge successful executions:
- `EXECUTIONS_DATA_PRUNE=true`
- `EXECUTIONS_DATA_MAX_AGE=168` (keep data for only 7 days)
- `EXECUTIONS_DATA_PRUNE_MAX_COUNT=50000`
- This keeps the database index small and prevents bloat on the `execution_entity` table.
Part 4: Open Community Close
Are you seeing execution locks or database lag on your self-hosted n8n instance during heavy AI or data ingestion pipelines? Drop your infrastructure specs (RAM, DB type, item volume) and current bottlenecks in the thread below, and let’s troubleshoot your queue configuration together.