How to merge two async workflows

Hey everyone,

I’m losing my mind over the Merge node. I have a simple workflow with two parallel branches (searching Accounts and Contacts in CRM). I just want to combine both results into a single JSON object.

But the Merge node either:

  • Only outputs data from ONE branch

  • Runs twice (first run has everything, second run is garbage)

  • Returns empty when I try to select the “missing” input

I’ve tried:

  • All merge modes (Combine, Append, Pass-through, etc.)

  • “Run once” vs default execution

  • Adding NoOp nodes

  • Waiting nodes to sync branches

Nothing works reliably.

The core issue here is that the Merge node in n8n waits for data from both inputs before passing through - but only works reliably when both branches complete within the same execution. The “runs twice” behavior you’re seeing is because the Merge node fires once per input it receives.

The fix: use Merge mode “Combine” with “Merge by Position”, and make sure both branches are triggered by the same single input (not separate triggers). Route your starting data to both branches simultaneously (split a single item to two paths), then feed both paths into the Merge node. If your two CRM lookups are async with unpredictable timing, the better pattern is to run them sequentially in a single flow using two HTTP Request nodes back-to-back, then use a Set node to combine the fields into one object.

Thanks @nguyenthieutoan for the explanation. We have found only reliable solution is to use n8n-nodes-join which works great.

Any combination of Merge is not producing reliable output. When first input is missing, it changes the index order etc. I wish the join would be in the core package.

Thanks!

Hi vladaman,
Thanks for sharing your setup and for the screenshot, this helps a lot.

From my experience as an n8n Verified Creator, n8n already gives you enough powerful core tools to handle most data-routing and merging scenarios safely, without having to rely on community nodes for this kind of logic. Community nodes can be great for prototyping, but for long‑term, production‑grade workflows I try to stick to core nodes only, because they are more predictable, maintained, and security‑reviewed.

In your specific case, the key is to “clean and normalize” each branch before you try to merge anything:

  • First, use Set/Edit Fields on each branch to enforce a consistent shape, for example:
    [{ requestId, source: "accounts", payload: [...] }] and [{ requestId, source: "contacts", payload: [...] }].

  • If each branch returns multiple items, you can then use the Aggregate node per branch to compress them into a single item like:
    [{ requestId, accounts: [...] }] and [{ requestId, contacts: [...] }].

  • Only after that, you merge the two final, well‑structured items (with Merge or even a small Code node) into one JSON object.

By doing this, you’re turning the problem from “merge two async streams with different cardinality and indexes” into “merge two clearly defined objects”, which is much more deterministic and doesn’t depend on fragile index alignment or timing. In practice, this has been far more reliable for me than trying different Merge modes or depending on a join‑style community node.

So short version: core n8n + Set/Edit Fields + (optional) Aggregate + a final Merge/Code node is usually all you need for this type of async CRM lookup use case.

Can you really use Code node to merge items from multiple sources somehow? I thought it having only one input would prevent it from being used that way.

I mean, I’m desperate for a solution here

The Code node itself only has one input, but that’s fine - the trick is to use it after you’ve already merged or aggregated the data into a single item. So the flow is: both branches run → Aggregate node compresses each branch into 1 item → Merge node (Combine mode) brings them together into 2 items in one execution → Code node receives those 2 items and you combine them like this:

const accounts = items[0].json;
const contacts = items[1].json;
return [{ json: { ...accounts, ...contacts } }];

The Code node isn’t doing the multi-source work - the Merge node before it handles that. The Code node just does the final shape you want.