Handling large JSON payloads and memory limits inside Code nodes during batch processing

Hi everyone,

I am currently building an automation workflow in n8n to process heavy data payloads and running into an execution hurdle during peak volume tasks.

Current Setup:

  • Self-hosted n8n instance handling high-frequency incoming data streams from multiple webhook and API endpoints.

  • Using advanced Code nodes (JavaScript) to parse, transform, and restructure deeply nested JSON objects before pushing them down to downstream apps.

The Challenge:

As the batch sizes grow larger, execution memory usage climbs significantly. Occasionally, large data arrays cause execution slowdowns or hit limits when handling massive item structures all at once within a single Code node execution block.

What best practices or workflow design patterns does this community recommend for chunking data efficiently, managing memory overhead, or optimizing large-scale payload transformations in n8n Code nodes?

Would love to hear any tips or scaling strategies from your production environments. Thanks!

Hey @Maaz, while you wait for a response, here are some things that might help:

Suggested resources

Automatically matched to your question.

Docs:

Forum:

@dmitrijz, @jabbson, @hubschrauber - you’ve helped with similar issues before, can you take a look?

Automatically suggested by n8n’s community bot. It’s a pilot - please share feedback here.

Hi @Maaz
Loop Over Items on its own won’t lower peak memory, the node keeps the original input and recombines every processed batch on the done output, so the full dataset still sits inside one execution. Move the transform out instead: Loop Over Items with a batch size in the low hundreds, then Execute Sub-workflow, with the Code node work living in the sub-workflow and returning only a small result set to the parent (ids, counts, a status). Memory frees after each batch rather than holding every item at once.
Run these through the trigger and not manual executions, manual runs make n8n copy the data for the frontend on top of what the execution already holds.
If you’re sizing the box for this kind of load, this covers it: