DEV Community

Pirate Prentice
Pirate Prentice

Posted on

n8n Merge Node: How to Combine Data from Multiple Branches (Free Workflow JSON)

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

  1. Trigger receives a user ID
  2. Branch A: HTTP Request → fetch profile from /api/users/{{ $json.userId }}
  3. Branch B: HTTP Request → fetch subscription from /api/subscriptions/{{ $json.userId }}
  4. Merge (Combine by Key) — join on userId
  5. Send Email with combined data

Both HTTP requests run in parallel, cutting latency vs. sequential fetches.

Reunite IF Branches

  1. IF node checks if customer is premium
  2. True branch: apply 20% discount code
  3. False branch: apply 5% discount code
  4. Merge (Append) — reunites both paths
  5. Send confirmation email to all

Aggregate Two API Sources

  1. HTTP Request → GitHub issues (branch A)
  2. HTTP Request → Linear tickets (branch B)
  3. Merge (Append) → unified list
  4. Sort by due date
  5. 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 }]] }
  }
}
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
pirateprentice profile image
Pirate Prentice

Quick reference: which Merge mode to pick

  • Append — two separate lists you want to combine (input 1 items first, then input 2)
  • Combine by position — both branches return the same number of items in the same order
  • Combine by key — SQL-style JOIN on a shared field (e.g., join on userId); unmatched items dropped by default
  • Choose Branch — you only need one branch's data downstream
  • Multiplex — every combination of items from both branches (3 × 4 = 12 outputs)

Most 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?