When your n8n workflow splits into multiple branches — an IF node, a Switch node, or parallel HTTP requests — you eventually need to bring those branches back together. That's what the n8n Merge node does.
This guide covers every merge mode, when to use each one, the gotchas that trip people up, and a free workflow JSON you can import today.
What the n8n Merge Node Does
The Merge node waits for data from two (or more) input branches and combines them into a single output stream. Without it, parallel branches stay separate and downstream nodes only see one branch at a time.
Common use cases:
- Enrich data: fetch user record from database (branch A) + fetch their orders from an API (branch B) → merge → send combined email
- Aggregate parallel lookups: call two external APIs simultaneously → merge results → write to Google Sheets
- Reunite IF branches: process different paths differently → merge back → log everything
Merge Modes
| Mode | What it does |
|---|---|
| Append | Concatenates all items from both inputs into one list. Input 1 items first, then input 2. |
| Combine | Joins items by position or by a matching key field (like a SQL JOIN). |
| Choose Branch | Passes through only one input's data. |
| Multiplex | Creates every combination of items from both inputs (cross join). |
Mode 1: Append
The simplest mode. Every item from input 1 is followed by every item from input 2 in the output.
Use it when:
- You have two separate lists to combine into one
- Order doesn't matter and there's no relationship between items across branches
- Aggregating results from parallel API calls
Example: Fetch active users from branch A, fetch trial users from branch B → Merge (Append) → write all to Google Sheets.
Mode 2: Combine
Combine joins items from both inputs either by position (index) or by a matching key field.
Combine by Position
Item 1 from input 1 pairs with item 1 from input 2, item 2 with item 2, etc. If one input has more items, extras are dropped by default.
Use it when: Both branches return data in the same order for the same records.
Combine by Key (SQL JOIN equivalent)
Matches items where a specified field has the same value.
- Input 1 Field:
id - Input 2 Field:
userId
Example: Input 1: { id: 1, name: "Alice" }, Input 2: { userId: 1, plan: "pro" } → Merge → { id: 1, name: "Alice", plan: "pro" }
Gotcha: Items with no matching key are dropped by default. Enable Unmatched Items for LEFT JOIN behavior.
Mode 3: Choose Branch
Passes through only one input's data. The other is discarded.
Use it when: You want to reunite flow after an IF node without mixing data from both branches — just resume a single stream for logging or a final step.
Mode 4: Multiplex
Creates every possible pairing of items from both inputs. 3 items × 4 items = 12 output items.
Use it when: Generating all combinations (e.g., every product × every region).
Warning: Output grows multiplicatively. 100 × 100 = 10,000 items. Always limit downstream.
Common Patterns
Parallel API Enrich → Combine
- Trigger receives a user ID
-
Branch A: HTTP Request → fetch profile from
/api/users/{{ $json.userId }} -
Branch B: HTTP Request → fetch subscription from
/api/subscriptions/{{ $json.userId }} -
Merge (Combine by Key) — join on
userId - Send Email with combined data
Both HTTP requests run in parallel, cutting latency vs. sequential fetches.
Reunite IF Branches
- IF node checks if customer is premium
- True branch: apply 20% discount code
- False branch: apply 5% discount code
- Merge (Append) — reunites both paths
- Send confirmation email to all
Aggregate Two API Sources
- HTTP Request → GitHub issues (branch A)
- HTTP Request → Linear tickets (branch B)
- Merge (Append) → unified list
- Sort by due date
- Google Sheets → write combined report
Gotchas Table
| Symptom | Root cause | Fix |
|---|---|---|
| Merge hangs, workflow never finishes | One branch never produces output (IF with empty false branch) | Use Choose Branch mode, or add a No Op node on the empty branch |
| Combine drops items unexpectedly | Key values don't match (case sensitive, type mismatch) | Log both inputs before merge; verify key values are identical strings |
| Output has duplicates | Append mode + looping trigger | Add Deduplicate node or check trigger fires only once |
| Merge waits forever | Upstream node errors silently | Enable "Continue on Fail" on upstream nodes; check execution log |
| Multiplex too many items | Large inputs × large inputs | Add LIMIT to source queries or Split In Batches downstream |
Free Workflow JSON — Parallel Enrich + Merge
This workflow fetches a user profile and subscription in parallel, merges by user ID, and responds with the combined record.
{
"name": "Parallel Enrich + Merge",
"nodes": [
{ "parameters": { "httpMethod": "POST", "path": "enrich-user", "responseMode": "responseNode" }, "name": "Webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 1, "position": [250, 300] },
{ "parameters": { "url": "=https://api.example.com/users/{{ $json.body.userId }}", "method": "GET" }, "name": "Get Profile", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [480, 200] },
{ "parameters": { "url": "=https://api.example.com/subscriptions/{{ $json.body.userId }}", "method": "GET" }, "name": "Get Subscription", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [480, 400] },
{ "parameters": { "mode": "mergeByKey", "propertyName1": "id", "propertyName2": "userId" }, "name": "Merge", "type": "n8n-nodes-base.merge", "typeVersion": 2, "position": [720, 300] },
{ "parameters": { "respondWith": "json", "responseBody": "={{ JSON.stringify($json) }}" }, "name": "Respond", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1, "position": [950, 300] }
],
"connections": {
"Webhook": { "main": [[{ "node": "Get Profile", "type": "main", "index": 0 }, { "node": "Get Subscription", "type": "main", "index": 0 }]] },
"Get Profile": { "main": [[{ "node": "Merge", "type": "main", "index": 0 }]] },
"Get Subscription": { "main": [[{ "node": "Merge", "type": "main", "index": 1 }]] },
"Merge": { "main": [[{ "node": "Respond", "type": "main", "index": 0 }]] }
}
}
Drop a comment with your use case and I'll share a customized version.
Workflow Starter Pack ($29)
Pre-built, production-ready n8n workflows with error handling, retry logic, and monitoring: n8n Workflow Starter Pack
Every workflow is tested, documented, and imports in under 2 minutes.
What do you use the Merge node for? Parallel API enrichment, reuniting IF branches, or aggregating multiple sources? Drop your pattern in the comments.
Top comments (1)
Quick reference: which Merge mode to pick
userId); unmatched items dropped by defaultMost common gotcha: if one IF branch returns 0 items, the Merge node hangs waiting forever. Fix: use Choose Branch mode, or add a No Op node to the empty branch.
Which Merge mode do you use most in your workflows?