Loading tutorials…
Loading tutorials…
Iterators and aggregators are how scenarios handle arrays — looping through records, batching API calls, building emails from lists. Get these wrong and one scenario can burn your entire monthly operations budget.
Who this is forOwners building scenarios that process collections (multiple line items in an order, multiple email addresses in a list, multiple search results from an API). Required for any non-trivial automation.
What you'll need
Step 1
Iterator = process each item in an array separately. Aggregator = combine multiple bundles into one. Use them together when looping then combining.
Iterator: takes an array (e.g., 50 line items) and creates 50 separate bundles, one per item. Each downstream module runs 50 times.
Use iterator when: you need to do something for each item. Example: "For each line item in the order, create a separate row in the inventory sheet."
Aggregator: takes multiple bundles and combines them into one. Example: "Combine 5 search results into a single email body."
Three aggregator types: Array Aggregator (combines into structured array), Text Aggregator (combines into one string), Numeric Aggregator (sums/averages).
Iterator + Aggregator pattern: split → process each item → combine back into one result. Very common pattern.
Step 2
Right-click upstream module → Add Module → Tools → Iterator. Configure the array field to iterate over.
Right-click the upstream module → "Add another module."
Search "Iterator" → add it.
In the Iterator config, set "Array" to the field from upstream that contains the array. Example: {{1.line_items}} for an order with multiple items.
Save. The Iterator now outputs N bundles where N = array length.
Add the action module after the Iterator. It will run once per item.
Important: every module DOWNSTREAM of the Iterator runs once per item. 50 items + 3 modules = 150 ops. Plan accordingly.
Step 3
After the modules that process iterated items, add an Aggregator to combine results back.
After your iterated processing modules, add an Aggregator module.
Pick the Aggregator type: Array (most common — combines into structured array), Text (combines into one string), or Numeric (math).
In the Aggregator config, set "Source Module" to the Iterator (or another upstream module if needed).
In "Aggregated fields," pick which fields from each iteration to include in the combined output.
For Text Aggregator: define a separator (comma, newline, custom string) and a wrapping format if needed.
After the Aggregator, downstream modules see ONE bundle (the combined result), not N bundles.
Step 4
Common pattern. Iterator → enrich each → Aggregator combines → single save module writes the combined record.
Use case: order has 5 line items. For each item, look up SKU info from a database. Combine all 5 enriched items into one shipping label.
Structure: Trigger (Order) → Iterator (line_items) → Database Lookup (per item) → Aggregator (combine enriched items) → Action (Create Shipping Label with full item list).
Without the Aggregator, you would create 5 shipping labels (one per item).
With the Aggregator, you create 1 shipping label with all 5 items combined.
This pattern saves significant operations vs duplicating the action 5 times.
Step 5
Between the Iterator and downstream modules, add a filter. Skips items that should not be processed.
Hover the line right after the Iterator → wrench icon → "Set up a filter."
Condition: e.g., "Skip items where quantity == 0" or "Only process items where category == digital."
Items that fail the filter are silently dropped from THIS iteration. Other items continue normally.
This is more efficient than processing then filtering after — filtered items consume zero ops on downstream modules.
Step 6
Build email bodies, Slack messages, or CSV strings by aggregating iterated items into one formatted string.
Use case: order confirmation email needs to list all items in the order.
After Iterator → add Text Aggregator.
Source: Iterator.
Text content (per item): "- {{name}} x {{quantity}} = ${{total}}"
Separator: newline.
Output: a single string like "- Widget x 2 = $40\n- Gadget x 1 = $30\n- Gizmo x 5 = $50"
Use this string in the email body. One email sent (1 op for email), regardless of item count.
Step 7
Before activating, calculate: trigger runs/day × array length × downstream modules = ops/day. Multiply by 30 for ops/month.
Open your operations forecast doc.
For each iterated scenario: estimate avg array length. Example: average order has 3 line items.
Calculate: trigger fires 50/day × 3 items × 4 modules per item = 600 ops/day = 18,000 ops/month.
Add 30% buffer for retries and edge cases.
Compare against your plan limit. If you are at 50% of the plan limit on one scenario, you cannot scale.
If the math does not work: reduce downstream modules per iteration, batch items into chunks, or upgrade plan.
Common mistakes
Iterating when batching would work
What goes wrong: Iterator on 100-item array with 5 downstream modules = 500 ops per run. Many APIs accept batched requests (send all 100 in one call) = 5 ops total. 100x ops difference for the same outcome.
How to avoid: Check if your downstream API supports batched/bulk operations (HubSpot bulk import, Stripe bulk, etc.). If yes, skip the Iterator and send the whole array in one call.
Not filtering inside iterations
What goes wrong: Iterator processes 100 items, 90 of which the downstream modules immediately filter out. 90% of the ops are wasted on items that contribute nothing.
How to avoid: Add a filter immediately after the Iterator to drop items that should not be processed. Filtered items consume zero ops on downstream modules.
Forgetting to add the Aggregator
What goes wrong: Iterator splits into 50 bundles. Downstream action fires 50 times. You wanted ONE consolidated email, you got 50 separate emails. Customer is furious.
How to avoid: If the goal is one consolidated output, ALWAYS pair Iterator with Aggregator. Iterator splits; Aggregator combines back.
Using Array Aggregator when Text Aggregator was needed
What goes wrong: Array Aggregator outputs a structured array. If you tried to use it as a string in an email body, you get '[object Object], [object Object], ...' instead of nice text.
How to avoid: Text Aggregator for strings (emails, reports). Array Aggregator for structured data (passing to APIs). Pick based on downstream consumption.
Not estimating ops cost before activating
What goes wrong: You activate a scenario with iterators, thinking it is normal cost. Discovers a week later it burned 80% of your monthly plan in 7 days. Other scenarios are paused.
How to avoid: Always math out iterated scenarios BEFORE activating: trigger frequency × array length × downstream modules. Compare to plan budget. Upgrade plan or redesign if cost is excessive.
Recap
Done — what's next
How to use Routers and Filters in Make.com
Read the next tutorial
Hand it off
Iterators and aggregators are where Make scenarios become powerful AND expensive. A specialist will design with operations efficiency, using batching where APIs allow. From $14-16/hr — most iteration-redesign projects land at $300-700 and pay back in operations savings within 2 months.
See specialist rates
Iterator: when processing items in an array (loop). Router: when branching based on conditions (decision tree). Iterators loop through data; routers split the flow. Different purposes.
Yes — 1 op per aggregator execution per batch. Compared to the iteration cost (1 op per item per downstream module), aggregator cost is negligible.
Yes, but be very careful. Iterator A (10 items) inside Iterator B (10 items) = 100 iterations per outer trigger. Quadruple the downstream module cost. Almost always avoidable with better data structure.
Use nested iterators OR flatten the array first with a Set Variable / Iterator combination. For most real cases, restructure the source data so you avoid nested arrays. Flat is cheaper.
No hard cap, but scenarios have a max execution time (default 40 min). An iterator on 10,000 items with downstream API calls will hit time limits. For large arrays, batch into chunks of 100-500 and process across multiple scenario runs.
Make
Routers and filters are how scenarios stop being linear toy automations and start handling real-world conditionality. This is the structure that prevents 1,000-line debug sessions.
Make
Production scenarios will fail. APIs go down, rate limits hit, data is malformed. The question is whether your scenario recovers gracefully or silently breaks. Error handlers are the difference.
Make
Data Stores are Make's built-in persistent storage. Scenarios are stateless by default; Data Stores give you memory across runs. This is the difference between toy automation and production infrastructure.
Make
Your scenario was working. Now it is failing. The diagnosis sequence specialists run is rarely random — there is a clear order that finds the root cause faster.