A single task is a chore; a thousand identical tasks is a system. Arrays and loops are the fundamental programming concepts that allow you to handle data at scale without writing redundant logic.
1Understanding Arrays
An Array is essentially a list. Instead of a variable holding one single value (like name = 'Alex'), an array holds a collection of values. In automation, when you fetch rows from a Google Sheet or contacts from a CRM, the data comes back as an array of structured JSON objects.
In n8n, this is the fundamental data model: every node produces an array of Items. Even if a trigger fires for just one record, it wraps that record in a single-element array. Once you internalize this, you'll stop being confused about why nodes behave differently on single vs. multiple inputs.
Arrays are zero-indexed, meaning the first element is at index 0. Accessing items[0] gives you the first item. This is one of the most common off-by-one bugs that trips up beginners — they try items[1] and wonder why they're missing the first record.
// Array of CRM contacts from Google Sheets
const contacts = [
{ id: 1, name: 'Alex', email: '[email protected]' },
{ id: 2, name: 'Sam', email: '[email protected]' },
{ id: 3, name: 'Jo', email: '[email protected]' }
];
// Access first item
console.log(contacts[0].name); // 'Alex'2The Power of Loops
A Loop repeats a set of instructions for every item in an array. The most common is the forEach pattern: take each item, run it through your logic, repeat until the array is exhausted. In n8n, most nodes do this automatically — if you connect a 'Send Email' node to a 50-item array, it sends 50 emails without you writing a single loop manually.
But sometimes you need explicit control. When you have complex conditional logic that changes *how* each item should be processed, or when you need to aggregate results before moving on, you reach for manual iteration constructs like n8n's SplitInBatches node or JavaScript's for...of loop inside a Code node.
The real skill is knowing when to let the platform loop for you and when to take over. Trusting automatic iteration for simple cases and writing explicit loops for complex cases keeps your workflows both lean and powerful.
// Explicit loop in n8n Code node
const items = $input.all();
const results = [];
for (const item of items) {
const processed = {
json: {
email: item.json.email,
greeting: `Hello, ${item.json.name}!`
}
};
results.push(processed);
}
return results;3Batching at Scale
When your array grows to thousands of items, you run into rate limits — the external API refuses to accept more than N requests per minute. The solution is batching: split your large array into smaller chunks and process one chunk at a time, with a deliberate pause between chunks.
In n8n, the Split In Batches node is your go-to. You set a batch size (e.g., 10), and it feeds items through in groups of 10, looping back until all items are done. Pair it with a Wait node (e.g., 1 second delay) between iterations and you've built a polite, rate-limit-safe processing pipeline.
The danger to watch for is the infinite loop bug: if your loop's exit condition is never triggered, the workflow runs forever until the server runs out of memory. Always verify your loop has a guaranteed termination path.
// n8n workflow structure
[Google Sheets: Get All Rows]
→ [Split In Batches: size=10]
→ [HTTP Request: Update CRM]
→ [Wait: 1 second]
→ [back to Split In Batches]
// 1,000 rows = 100 batches
// Total time ~100 seconds