Looping and Iteration in n8n Workflows

This article explains how n8n handles looping automatically and when you need manual control. Discover practical methods like the Loop Over Items node, conditional loops with IF, and advanced techniques for efficient iteration in your n8n workflows.
Master Looping & Iteration in n8n Workflows

Looping and iteration in n8n workflows allow you to process multiple items or repeat actions efficiently, forming the backbone of many powerful automations. While n8n cleverly handles most iteration automatically by running nodes once for each incoming item, understanding when and how to implement explicit loops is crucial for tasks like handling paginated API results, processing data in batches to avoid rate limits, or implementing retry logic. This guide dives into n8n’s default iteration behavior, explores different methods for creating manual loops using nodes like “Loop Over Items” and “IF,” and provides practical examples and best practices to make your workflows more robust and dynamic.

The Magic Behind n8n’s Automatic Iteration

First things first, let’s talk about how n8n usually works its magic without you needing to build complex loops. Most n8n nodes are designed to iterate automatically. What does that mean? Imagine you have a node that outputs a list of 10 customer emails, and the next node is supposed to send a welcome email.

By default, n8n is smart enough to take that list of 10 items and run the “Send Email” node ten separate times, once for each email address. You don’t need to tell it, “Hey, do this 10 times!” It just… does it. Each run processes one item from the input list. Think of it like an assembly line – each item (email) gets processed individually by the next station (node).

This is fantastic for simplicity! For many common tasks, like processing all rows from a spreadsheet or handling multiple webhook payloads that arrive together, n8n’s built-in item-by-item processing is exactly what you need.

But What If You Don’t Want That? The Execute Once Setting

Occasionally, you might get multiple items flowing into a node, but you only want the node to run once using the data from the first item. Maybe you’re fetching a list of users but only need to send a single summary notification, not one per user.

In these cases, most nodes have a handy setting. Click the node, go to its Settings tab, and you’ll often find a toggle called Execute Once. Flip that on, and the node will ignore items 2, 3, 4, etc., and only execute a single time based on the first item it receives. Simple, right?

When You Need to Take the Reins: Explicit Looping

Okay, so n8n handles the basics automatically. But the real world of automation is messy! Sometimes, the default behavior isn’t enough. You’ll need to build explicit loops when:

  1. Handling Paginated APIs: An API gives you results in “pages” (e.g., 100 contacts per page). You need to fetch page 1, then page 2, then page 3, until there are no more pages. n8n’s HTTP Request node won’t automatically do this pagination for you.
  2. Processing in Batches: You have 1000 items, but the service you’re sending them to has a rate limit (e.g., only 10 requests per minute). You need to process items in small batches with pauses in between.
  3. Conditional Retries: You want to try an action, check if it succeeded, and if not, wait and retry a few times before giving up.
  4. Specific Node Behavior: Some nodes, particularly certain database operations (like INSERT or UPDATE in some nodes) or the Code node in specific modes, are designed to run only once, even with multiple input items. The n8n documentation (and the reference content provided!) lists these exceptions.

So, how do we build these manual loops? Let’s explore the main methods.

Method 1: The Conditional Loop (Using IF Node)

This is a classic programming loop pattern, recreated visually in n8n. You essentially make the workflow circle back on itself, using an IF node to decide whether to continue looping or break out.

How it works:

  1. Initialize: Often starts with a node (Set or Code) to set up an initial state (e.g., pageNumber = 1).
  2. Action: Perform the core task (e.g., HTTP Request to fetch the current page).
  3. Process: Handle the data from the action (e.g., extract contacts from the API response).
  4. Check Condition: Use an IF node to check if the loop should continue. The condition could be:
    • “Did the API response indicate there’s a ‘next page’?”
    • “Is retryCount less than 3?”
    • “Did the previous step return any results?”
  5. Loop or Exit:
    • If the condition to continue looping is TRUE (or FALSE, depending on how you set it up), connect that branch back to an earlier node (often just before the Action step, potentially after updating a counter like pageNumber).
    • If the condition to exit the loop is met, connect that branch to the rest of your workflow.

Analogy: Think of asking “Are we there yet?” on a road trip. If the answer is “No” (condition to continue), you keep driving (loop back). If the answer is “Yes” (condition to exit), you stop driving and get out (continue to the next part of the workflow).

Challenge: You MUST have a reliable exit condition, or you’ll create an infinite loop that could crash your n8n instance!

Method 2: Processing Item by Item or in Batches (Loop Over Items Node)

This is often the go-to method for processing a known list of items sequentially or in controlled batches. The node used to be called “Split In Batches,” but now it’s more intuitively named Loop Over Items.

How it works:

  1. Input: Feed the node the list of items you want to process (e.g., 50 email addresses).
  2. Configure:
    • Batch Size: Set this to 1 if you want to process each item individually. Set it to a higher number (e.g., 10) if you want to process items in batches (useful for rate limiting).
    • Looping: This node inherently creates a loop structure. It outputs one batch (or one item if batch size is 1) through its main output path.
  3. Action: Connect the nodes that perform the action on that single item or batch (e.g., Save to Database, Send Slack Message).
  4. Loop Back: Critically, you must connect the last node in your item-processing sequence back to the input of the Loop Over Items node. This tells n8n, “Okay, I’m done with this item/batch, send me the next one.”
  5. Completion: Once all items/batches have been processed, the Loop Over Items node sends a final signal through its second output path (usually labeled “Done” or similar), allowing the rest of your workflow to continue.

Real-World Example (from Community): Imagine fetching multiple emails with an IMAP Trigger. If you process them normally, data might get mixed up in later merge nodes. Using Loop Over Items with a batch size of 1 ensures each email goes through the entire subsequent process (saving attachments, updating CRM, etc.) completely before the next email starts its journey.

Benefit: Great for ensuring sequential processing and managing rate limits gracefully.

Method 3: Getting Clever with $runIndex (The “Good” Way)

This approach, highlighted in one of the n8n blog posts, is a bit more advanced but can be incredibly elegant, especially for pagination or when you just need a simple counter.

The Secret Sauce: $runIndex

Every time a node executes within a single workflow run, n8n internally keeps track of how many times that specific node has run. This count is available as $runIndex within expressions for that node. The first time it runs, $runIndex is 0, the second time 1, the third time 2, and so on.

How it works (for Pagination):

  1. Initial Action (inside the loop): Start your loop directly with the HTTP Request node. In its URL parameter, use an expression like: https://api.example.com/items?page={{ $runIndex + 1 }}. (We add 1 because $runIndex starts at 0, but page numbers usually start at 1).
  2. Process: Extract the data you need. Crucially, also check if there are more results or determine the total number of pages from the response (if available).
  3. Check Condition (IF Node): Use an IF node. Compare the current run index to the total number of pages, or check if a “next page” indicator exists. For example: {{ $runIndex + 1 < $json.totalPages }}.
  4. Loop or Exit:
    • If the condition to continue is TRUE, connect the IF node’s true output directly back to the input of the HTTP Request node. Because it’s looping back, the next time the HTTP Request node runs, its $runIndex will automatically be incremented! Magic!
    • If the condition is FALSE (you’ve processed the last page), connect the false output to the rest of your workflow.

Benefit: Often requires fewer nodes (no separate Set node to manually increment a counter), making the workflow cleaner. Requires a bit more conceptual understanding of $runIndex.

Real-World Scenario: Handling API Pagination Robustly

Let’s tie this together. You need to fetch all contacts from an API that returns 50 contacts per page.

  1. Choose a Method: The $runIndex method is quite elegant here.
  2. HTTP Request Node:
    • URL: https://mycrm.api/contacts?page={{ $runIndex + 1 }}&limit=50
    • Make sure to configure authentication.
  3. Process Node(s): (Could be a Set or Code node)
    • Extract the contacts: {{ $json.data }}
    • Check for more pages. Does the API return totalPages? Or a nextPageUrl? Let’s assume it returns hasMore: true/false. Store this: {{ $json.meta.hasMore }}.
  4. IF Node:
    • Condition: Check the hasMore value you extracted. Set the condition to Boolean: {{ $json.hasMore }} is true.
  5. Connect:
    • Connect the TRUE output of the IF node back to the input of the HTTP Request node.
    • Connect the FALSE output of the IF node to the next step (e.g., a node to process all collected contacts).

Data Accumulation: Wait, how do you get all the contacts from all the pages at the end? When the loop finishes, the final node only has the data from the last iteration. You’ll need a way to gather results. Often, a Code node after the loop finishes is used. You can access data from all runs of a specific node using $items('Node Name'). You might loop through these results in the Code node to build a final combined list. (See the Site 3 blog post code snippet for an example using $items('Node Name', 0, index) within a loop inside the Code node).

Avoiding Common Looping Pitfalls

  • Infinite Loops: ALWAYS double-check your exit condition in conditional loops (Method 1 & 3). Make sure it will eventually become false. Test thoroughly!
  • Data Accumulation: Plan how you’ll gather results from all iterations if needed. Using $items() after the loop is common. The Loop Over Items node handles accumulation differently; its “Done” output often contains results depending on settings.
  • Complex Endpoints: If your loop logic inside Loop Over Items has multiple IF branches leading to different “end” points within that loop iteration, connecting all of them back to the Loop node input can get messy. As suggested in the community thread (Site 2), consider putting the core loop logic into a sub-workflow (using Execute Workflow node) called by the main loop. This keeps the main workflow cleaner.

Looping Exceptions: Know Your Nodes

Remember that list of nodes that don’t automatically loop? Keep them in mind:

  • HTTP Request: Doesn’t handle pagination automatically. You need explicit looping.
  • Database Nodes (some operations): Nodes like CrateDB, Microsoft SQL, MongoDB, QuestDB, TimescaleDB might execute INSERT or UPDATE only once per run, even with multiple items. Check node documentation.
  • Code Node (Run Once for All Items mode): Explicitly designed to get all items at once for custom code processing.
  • Execute Workflow (Run Once for All Items mode): Similar to the Code node mode.
  • Others: Check the official n8n docs for specific node behaviors if unsure.

Wrapping Up

Looping in n8n is a powerful concept. While n8n’s default item-by-item processing handles many scenarios beautifully, mastering explicit loops unlocks the ability to tackle complex, real-world automation challenges like pagination, batch processing, and retries.

Whether you choose the visual feedback loop with an IF node, the structured approach of the Loop Over Items node, or the elegant $runIndex technique, understanding these patterns is key to becoming an n8n pro. Don’t be afraid to experiment (carefully!), test your exit conditions, and consult the docs or community if you get stuck. Happy automating!

Leave a Reply

Your email address will not be published. Required fields are marked *

Blog News

Other Related Articles

Discover the latest insights on AI automation and how it can transform your workflows. Stay informed with tips, trends, and practical guides to boost your productivity using N8N Pro.

Your First n8n Workflow: A Simple Automation Example

Dive into n8n automation by building your very first workflow. This guide provides a simple, practical example to...

Saving and Sharing Your n8n Workflows

Discover how to effectively save and share your n8n workflows. This article covers exporting, importing, and team collaboration...

Understanding the n8n Interface: A Beginner’s Guide

This guide walks beginners through the essential components of the n8n interface, including the workflow editor, canvas, nodes...

Understanding n8n Expressions: Dynamic Data Handling

Discover the power of n8n expressions for dynamic data handling. This guide explains how to use expressions, access...

Data Transformation in n8n: Using the Function Node

Discover the power of n8n's Function Node for advanced data transformation tasks. This guide covers essential concepts, practical...