The idea is:
Add a high-performance bulk insert mode to the PostgreSQL node that internally builds multi-row INSERT statements (and/or uses a COPY-like mechanism) with reduced per-item validation. The node would:
- Group incoming items into batches.
- For each batch, generate and execute a single multi-row
INSERT(e.g.INSERT INTO table (col1, col2) VALUES (…), (…), …). - Minimize per-item overhead when the user explicitly opts into this “bulk/fast” mode.
- Optionally expose a “reduced validation / unsafe” toggle, making it clear that performance is favored over strict per-item checks.
My use case:
I regularly need to insert large volumes of data into PostgreSQL (e.g. thousands to hundreds of thousands of rows) via n8n.
-
Using the current PostgreSQL node insert:
- ~1,000 records take around 4 seconds, regardless of the batch option (single, independent, transaction).
- ~200,000 records can take roughly 10 minutes, even when split into batches of 1,000.
- The performance issue appears to come from per-item validation and checks done by the node.
-
As a workaround, I:
- Use a Code node to build a single multi-row INSERT statement, like:
INSERT INTO table (columns) VALUES (value1), (value2), … - Execute that statement via the PostgreSQL node.
- Use a Code node to build a single multi-row INSERT statement, like:
-
With this approach:
- 1,000 records go from ~4 seconds to ~500 ms.
- 200,000 records go from ~10 minutes to about 30 seconds.
-
However, this workaround has drawbacks:
- I must manage query length limits myself (e.g. Loop → Aggregate 10,000 items → Code building INSERT).
- More complex workflow logic (loops, aggregation, code).
- Potentially higher CPU/RAM usage in a single large workflow.
- If I tried to move this to sub-workflows/webhooks, I would create a lot of extra execution history noise for what is logically one bulk operation.
I also considered generating CSV and using
COPY FROMdirectly on the server, but this requires direct access to the PostgreSQL server, which I often don’t have in shared/managed environments.
I think it would be beneficial to add this because:
-
It would make large-scale ingestion into PostgreSQL much more practical and efficient within n8n.
-
It would:
- Eliminate the need for custom Code nodes just to build multi-row INSERTs.
- Remove the need for manual batching logic (loops + aggregation nodes).
- Allow a single PostgreSQL node to handle bulk inserts cleanly, keeping workflows simpler and execution history clearer.
-
It aligns better with how PostgreSQL is optimized to work (multi-row INSERTs, potentially COPY) rather than per-row operations.
-
Users could explicitly opt into a “fast/bulk” mode when they care more about performance than per-item validation, which is a common pattern in ETL/bulk load scenarios.
Any resources to support this?
-
PostgreSQL documentation and common best practices recommend:
- Multi-row
INSERTstatements over large numbers of single-row inserts for performance. COPY(from CSV or binary) for very high-volume data loading.
- Multi-row
-
My own benchmarks:
- ~1,000 rows: ~4s with current node vs. ~500ms with manually built multi-row INSERT.
- ~200,000 rows: ~10 minutes with current node vs. ~30 seconds with manual multi-row INSERT in batches.
Are you willing to work on this?
I’m happy to provide:
- Example workflows (current vs. bulk workaround).
- Benchmarks and test data.
- Feedback on proposed designs or configuration options for the bulk insert mode.