G: “
Hello n8n enthusiasts and data wranglers! 👋 Are you ready to truly master the art of data transformation within n8n? Today, we’re diving deep into one of n8n’s most powerful yet sometimes underutilized tools: the Aggregation Node. This node is your secret weapon for summarizing, combining, and structuring data in ways that streamline your workflows and unlock new possibilities.
Whether you’re preparing data for a complex API, generating insightful reports, or simply cleaning up messy inputs, the Aggregation node can revolutionize your n8n experience. Forget manual data crunching – let’s automate it!
In this comprehensive guide, we’ll explore 10 practical scenarios and techniques that will turn you into an Aggregation node maestro. Let’s get started! 🚀
Understanding the Core Concept: What is the Aggregation Node? 🤔
At its heart, the n8n Aggregation node takes multiple incoming items and combines them into a single item or a set of grouped items based on specified criteria. Think of it as a data “blender” or “summarizer.”
It’s particularly useful when you have a list of individual items (e.g., rows from a spreadsheet, records from a database query) and you need to:
- Combine them all into one object/array.
- Calculate a sum, average, count, or other statistic.
- Group items based on a common field (e.g., group all sales by customer).
- Extract specific items (e.g., the first or last item in a group).
The two primary Output Modes
you’ll encounter are:
Aggregate
: All incoming items are combined into a single output item. Ideal for generating a single summary or preparing an array for an API.Grouped
: Items are grouped based on a specified field (theGroup By
property), and an output item is generated for each unique group. Perfect for creating per-category summaries.
Now, let’s explore the practical magic! ✨
1. Simple Merging & Batching: Combining All Items into One List 📦
One of the most common uses of the Aggregation node is to simply take a list of items and turn them into a single array under one property. This is incredibly useful when an API expects an array of objects.
Scenario: You have a list of user objects from a database query, and you need to send them as a single array to an external user management API.
n8n Setup:
- Output Mode:
Aggregate
- Properties:
- Add Property:
users
- Operation:
Push
- Value:
{{ $json }}
(This will push the entire incoming JSON item into theusers
array.)
- Add Property:
Input Data Example:
[
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" },
{ "id": 3, "name": "Charlie" }
]
Output Data Example:
[
{
"users": [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" },
{ "id": 3, "name": "Charlie" }
]
}
]
Why it’s useful: This single output item, containing the users
array, can then be directly mapped to an API request body, simplifying your workflow immensely. No more looping over individual items for batch operations!
2. Summing Numerical Data: Total Revenue Calculation 💰
Need to quickly add up a column of numbers? The Aggregation node makes it trivial.
Scenario: You have a list of sales transactions, and you want to calculate the total revenue for the day.
n8n Setup:
- Output Mode:
Aggregate
- Properties:
- Add Property:
totalRevenue
- Operation:
Sum
- Value:
{{ $json.amount }}
- Add Property:
Input Data Example:
[
{ "orderId": "A1", "amount": 100.50 },
{ "orderId": "B2", "amount": 25.00 },
{ "orderId": "C3", "amount": 75.25 }
]
Output Data Example:
[
{
"totalRevenue": 200.75
}
]
Tip: Ensure the Value
you’re summing is indeed a numerical type. If it’s a string, you might need a Set
node beforehand to convert it using {{ parseFloat($json.amount) }}
.
3. Calculating Averages: Performance Metrics 📈
Beyond summing, you can also easily find the average of numerical data.
Scenario: You have a list of website page load times, and you want to find the average load time to monitor performance.
n8n Setup:
- Output Mode:
Aggregate
- Properties:
- Add Property:
averageLoadTimeMs
- Operation:
Average
- Value:
{{ $json.loadTimeMs }}
- Add Property:
Input Data Example:
[
{ "page": "/home", "loadTimeMs": 1200 },
{ "page": "/product", "loadTimeMs": 800 },
{ "page": "/about", "loadTimeMs": 1400 },
{ "page": "/contact", "loadTimeMs": 1000 }
]
Output Data Example:
[
{
"averageLoadTimeMs": 1100
}
]
This is perfect for quick reports or dashboards!
4. Counting Items: User Sign-ups & Item Totals 📊
The Count
operation is simple but incredibly useful for getting totals.
Scenario: You want to know the total number of new user sign-ups from a list of records.
n8n Setup:
- Output Mode:
Aggregate
- Properties:
- Add Property:
totalSignUps
- Operation:
Count
- Value:
{{ $json.id }}
(You can pick any property that exists on each item, as we’re just counting the items themselves.)
- Add Property:
Input Data Example:
[
{ "id": 101, "email": "a@example.com" },
{ "id": 102, "email": "b@example.com" },
{ "id": 103, "email": "c@example.com" }
]
Output Data Example:
[
{
"totalSignUps": 3
}
]
Pro Tip: If you combine Count
with Grouped
output mode (see next point!), you can count items per group – e.g., “how many users signed up from each country?”.
5. Grouping Data for Reports: Sales by Product Category 📋
This is where the Group By
feature shines, allowing you to create summaries for distinct categories.
Scenario: You have sales data for various products and want to generate a report showing total sales for each product category.
n8n Setup:
- Output Mode:
Grouped
- Group By:
{{ $json.category }}
- Properties:
- Add Property:
category
- Operation:
First
- Value:
{{ $json.category }}
(To include the category name in the output) - Add Property:
totalSales
- Operation:
Sum
- Value:
{{ $json.amount }}
- Add Property:
numberOfItemsSold
- Operation:
Count
- Value:
{{ $json.amount }}
(Counts items within each group)
- Add Property:
Input Data Example:
[
{ "product": "Laptop", "category": "Electronics", "amount": 1200 },
{ "product": "Mouse", "category": "Electronics", "amount": 25 },
{ "product": "T-Shirt", "category": "Apparel", "amount": 30 },
{ "product": "Keyboard", "category": "Electronics", "amount": 75 },
{ "product": "Jeans", "category": "Apparel", "amount": 50 }
]
Output Data Example:
[
{
"category": "Electronics",
"totalSales": 1300,
"numberOfItemsSold": 3
},
{
"category": "Apparel",
"totalSales": 80,
"numberOfItemsSold": 2
}
]
This is incredibly powerful for generating segment-specific data!
6. Extracting First/Last Items: Latest Updates or Initial Records 🕰️
Sometimes you don’t need a sum or average, but rather a specific item from a sequence or group.
Scenario: You’re tracking customer support tickets, and for each customer, you want to know their last opened ticket and their first opened ticket. (Assume input data is sorted by date for simplicity, or use a Sort
node beforehand.)
n8n Setup:
- Output Mode:
Grouped
- Group By:
{{ $json.customerId }}
- Properties:
- Add Property:
customerId
- Operation:
First
- Value:
{{ $json.customerId }}
- Add Property:
firstTicketId
- Operation:
First
- Value:
{{ $json.ticketId }}
- Add Property:
lastTicketSubject
- Operation:
Last
- Value:
{{ $json.subject }}
- Add Property:
Input Data Example:
[
{ "customerId": "C1", "ticketId": "T101", "subject": "Login Issue", "date": "2023-01-15" },
{ "customerId": "C2", "ticketId": "T102", "subject": "Payment Error", "date": "2023-01-16" },
{ "customerId": "C1", "ticketId": "T103", "subject": "Password Reset", "date": "2023-01-20" },
{ "customerId": "C2", "ticketId": "T104", "subject": "Product Inquiry", "date": "2023-01-22" }
]
Output Data Example:
[
{
"customerId": "C1",
"firstTicketId": "T101",
"lastTicketSubject": "Password Reset"
},
{
"customerId": "C2",
"firstTicketId": "T102",
"lastTicketSubject": "Product Inquiry"
}
]
Remember to sort your data before the Aggregation node if the “first” or “last” depends on a specific order (like date). A Sort
node is perfect for this.
7. Conditionally Aggregating Data: Summing “Active” Records Only 🎯
You might only want to aggregate data that meets certain criteria. While the Aggregation node itself doesn’t have an IF
condition, you can easily combine it with an IF
node or Set
node upstream.
Scenario: You have a list of projects with their budget, and you only want to sum the budget of projects that are currently “active”.
n8n Setup:
IF
Node (before Aggregation):- Mode:
All True
- Conditions:
Value1: {{ $json.status }}
|Operation: Is Equal
|Value2: active
- Mode:
Aggregation
Node: (Only receives “active” projects from theTrue
branch of the IF node)- Output Mode:
Aggregate
- Properties:
- Add Property:
totalActiveBudget
- Operation:
Sum
- Value:
{{ $json.budget }}
- Add Property:
- Output Mode:
Input Data Example (to IF
node):
[
{ "project": "Website Redesign", "status": "active", "budget": 50000 },
{ "project": "New Feature Dev", "status": "on_hold", "budget": 20000 },
{ "project": "Marketing Campaign", "status": "active", "budget": 15000 }
]
Output Data Example (from Aggregation node):
[
{
"totalActiveBudget": 65000
}
]
This pattern allows for highly flexible and targeted aggregation!
8. Creating Custom Aggregation Logic: Concatenating Strings or Complex Calculations 🧠
For scenarios not covered by the standard Sum
, Average
, Count
, etc., you can use the JavaScript expression
as your Value
field within an aggregation operation.
Scenario: You want to create a comma-separated list of all unique product names sold within a specific category.
n8n Setup:
-
Output Mode:
Grouped
-
Group By:
{{ $json.category }}
-
Properties:
- Add Property:
category
- Operation:
First
- Value:
{{ $json.category }}
- Add Property:
uniqueProductsList
- Operation:
Push
(This pushes all individual product names into an array for each group) - Value:
{{ $json.productName }}
- Add Property:
-
Then, add a
Set
node after theAggregation
node to process theuniqueProductsList
array for each group:- Mode:
Keep only Set
- Add Value:
uniqueProductsString
- Value:
{{ Array.from(new Set($json.uniqueProductsList)).join(', ') }}
(This converts the array to a Set to get unique values, then converts back to array and joins them).
- Mode:
Input Data Example (to Aggregation node):
[
{ "productName": "Laptop", "category": "Electronics" },
{ "productName": "Mouse", "category": "Electronics" },
{ "productName": "Keyboard", "category": "Electronics" },
{ "productName": "T-Shirt", "category": "Apparel" },
{ "productName": "Jeans", "category": "Apparel" },
{ "productName": "Mouse", "category": "Electronics" } // Duplicate
]
Output Data Example (from Set
node after Aggregation):
[
{
"category": "Electronics",
"uniqueProductsList": ["Laptop", "Mouse", "Keyboard"],
"uniqueProductsString": "Laptop, Mouse, Keyboard"
},
{
"category": "Apparel",
"uniqueProductsList": ["T-Shirt", "Jeans"],
"uniqueProductsString": "T-Shirt, Jeans"
}
]
This technique showcases combining the Aggregation node’s grouping power with JavaScript for custom post-processing!
9. Preparing Data for API Batch Updates: Chunking Items 🔄
Many APIs have limits on how many records you can update in a single request. The Aggregation node, combined with Item Lists
or clever Group By
logic, can help you chunk your data.
Scenario: You have 1000 customer records to update, but your CRM API only allows 100 records per batch update.
n8n Setup:
Code
Node (orItem Lists
node configured as “Batch” if available): Generate items with anindex
property.Set
Node (before Aggregation): Add abatchId
property to each item using an expression like{{ Math.floor($item.index / 100) }}
. This will assign batch IDs 0, 0, …, 0 (for first 100 items), then 1, 1, …, 1 (for next 100), etc.Aggregation
Node:- Output Mode:
Grouped
- Group By:
{{ $json.batchId }}
- Properties:
- Add Property:
batchId
- Operation:
First
- Value:
{{ $json.batchId }}
- Add Property:
customers
- Operation:
Push
- Value:
{{ $json }}
(Push the whole customer object)
- Add Property:
- Output Mode:
Input Data Example (after Set
node):
[
{ "id": 1, "name": "A", "batchId": 0 },
{ "id": 2, "name": "B", "batchId": 0 },
// ... 98 more items with batchId: 0
{ "id": 101, "name": "AA", "batchId": 1 },
{ "id": 102, "name": "BB", "batchId": 1 }
// ... etc.
]
Output Data Example:
[
{
"batchId": 0,
"customers": [
{ "id": 1, "name": "A", "batchId": 0 },
{ "id": 2, "name": "B", "batchId": 0 }
// ... 98 more customers
]
},
{
"batchId": 1,
"customers": [
{ "id": 101, "name": "AA", "batchId": 1 },
{ "id": 102, "name": "BB", "batchId": 1 }
// ... etc.
]
}
]
Each output item from the Aggregation node now represents a perfectly sized batch ready for your API calls. You can then use an HTTP Request
node after this, and it will iterate over each of these batched items.
10. Handling Missing Data Gracefully: Default Values for Aggregation 🛡️
When performing numerical aggregations (Sum, Average), sometimes your input data might have missing or null values. This can lead to unexpected results. You can use JavaScript expressions to provide default values.
Scenario: You’re summing price
values, but some items might have a null
or missing price
field. You want these to count as in the sum.
n8n Setup:
- Output Mode:
Aggregate
- Properties:
- Add Property:
totalPrice
- Operation:
Sum
- Value:
{{ $json.price || 0 }}
(This uses the logical OR operator: if$json.price
is null, undefined, 0, or an empty string, it will default to.)
- Add Property:
Input Data Example:
[
{ "item": "Shirt", "price": 25 },
{ "item": "Hat", "price": null },
{ "item": "Shoes", "price": 70 },
{ "item": "Socks" } // 'price' property is missing
]
Output Data Example:
[
{
"totalPrice": 95
}
]
Without || 0
, a Sum
operation encountering null
or undefined
might yield null
or NaN
(Not a Number) for the whole sum, or simply ignore the item depending on the n8n version and specific context. Using || 0
ensures robust calculation.
Advanced Tips for Aggregation Node Mastery ✨
- Pre-process with
Set
orCode
Nodes: Often, your raw input data isn’t perfectly structured for aggregation. UseSet
nodes to rename properties, convert data types (e.g., string to number), or create new properties (batchId
as seen above) before sending to the Aggregation node. ACode
node offers ultimate flexibility for complex transformations. - Sort Before Aggregating
First
/Last
: As mentioned in Guide 6, if the “first” or “last” item is meaningful based on a specific order (like date or numerical ID), always use aSort
node before the Aggregation node. - Combine with
Loop
orItem Lists
: For more complex batching scenarios, or when you need to process each aggregated group individually (e.g., send an email per group), the Aggregation node works perfectly withLoop
orItem Lists
nodes to manage iterations. - Error Handling: Consider what happens if the
Value
property for aggregation is missing on all items. Depending on the operation, it might returnnull
or. Be prepared for these edge cases in downstream nodes.
- Performance on Large Datasets: For extremely large datasets (thousands or tens of thousands of items), be mindful of memory usage. While n8n handles many items efficiently, very complex aggregations on massive inputs might benefit from breaking down the workflow or performing some aggregation directly in a database query if possible.
Conclusion 🎉
Congratulations! You’ve just taken a massive leap in mastering the n8n Aggregation node. From simple data merging to complex, grouped reports and API batching, you now have 10 powerful techniques in your arsenal.
The Aggregation node is a cornerstone for efficient data processing in n8n. By understanding its Output Modes
, Group By
capabilities, and various Operations
, you can build incredibly robust and streamlined workflows.
What’s next?
- Practice! Open n8n, create a new workflow, and try implementing some of these examples yourself.
- Experiment! Try combining different operations, chaining Aggregation nodes, or integrating them into your existing workflows.
- Share! If you discover a new, ingenious way to use the Aggregation node, share it with the n8n community!
Happy automating! And remember, with the Aggregation node, your data is always at your command. 💪