How to Use Parallel Nodes for Data Enrichment
Speed up workflows by enriching data from multiple sources simultaneously.
What This Integration Does
Enrichment workflows take a thin input (an email address, an order ID, a customer ID) and fan out to multiple systems to assemble a fuller picture - CRM record, order history, support tickets, marketing engagement. Done sequentially, this is as slow as the sum of every API call. Done with a Spojit Parallel node, each lookup runs concurrently and the total time is roughly the slowest single call.
The pattern is consistent regardless of the data sources: a Parallel node fans out into several branches, each branch does whatever lookup or computation it needs, and the parent workflow resumes once every branch has finished. A Transform node downstream combines the per-branch results into a single shaped object the rest of the workflow uses.
Prerequisites
- At least one identifier on the incoming record - typically an email, customer ID, or external reference.
- Connections to each enrichment source - for example shopify, klaviyo, mongodb, or a custom REST API via http.
- An understanding of which lookups are independent (good Parallel candidates) versus which depend on another's output (must stay sequential).
Step 1: Receive or Construct the Input Record
Start with whatever Trigger brings the record in - webhook from your CRM, schedule polling a queue, or a Subworkflow call from a parent. The trigger output should expose the identifiers each branch needs. If you have an email but need a customer ID, add a quick Connector step that resolves it before the fan-out.
Step 2: Add a Parallel Node
Drop a Parallel node after the input step. Each branch is a sequence of one or more nodes that share access to the parent state but run independently. Aim for 2 to 6 branches - more than that and you'll start hitting per-connector concurrency limits or rate caps on the underlying APIs.
Step 3: Branch 1 - Look Up the Customer Profile
The first branch queries your customer system. For a Shopify-backed business, that's a Connector node calling shopify get-customer with the customer ID. For NetSuite, use netsuite get-customer. Bind the result so the merge step can pick fields out of {{ branch1.customer }}.
Step 4: Branch 2 - Pull Order History
The second branch fetches recent activity. Use shopify list-orders filtered by customer ID, or woocommerce list-orders, or a query against your data warehouse via mongodb find-documents. Use the array connector's length tool to count orders and sort to surface the most recent - these numbers are usually what enrichment consumers actually want.
Step 5: Branch 3 - Marketing Engagement and Support Tickets
The third branch enriches with engagement signals. Use klaviyo get-profile and klaviyo list-events to pull recent campaign opens, clicks, and conversions. For support tickets use front list-conversations filtered by the customer's email. Each lookup runs concurrently with the customer and order branches, so the slowest one bounds the total time.
Step 6: Merge Branch Results with a Transform
After the Parallel node, add a Transform node that combines the per-branch outputs into a single shaped object:
{
"customerId": "{{ branch1.customer.id }}",
"email": "{{ branch1.customer.email }}",
"orderCount": {{ branch2.orders.length }},
"lastOrderAt": "{{ branch2.orders[0].created_at }}",
"klaviyoSegments": {{ branch3.profile.segments }},
"openSupportTickets": {{ branch3.tickets.open }}
}
Pass this object onwards - to a downstream Connector node that writes the enriched profile back into your CRM, an AI step that scores the customer, or a Condition that routes high-value customers differently.
Tips
- Branches don't have to be balanced - one branch can be a single Connector call while another is five steps deep.
- If branches share an expensive precondition (like resolving an OAuth token), do that step before the Parallel node and pass the result in.
- Wrap each branch's main call in its own Condition for graceful degradation - one slow vendor shouldn't block the whole enrichment if its data is non-critical.
- Knowledge base lookups slot naturally into a branch via the Knowledge node when you want internal context (FAQs, playbooks) merged with external data.
Common Pitfalls
- Hidden sequential dependencies - if branch 2 actually needs branch 1's output, the Parallel breaks. Move the dependent work after the Parallel or restructure into a chain.
- Rate limits - hammering one provider from many parallel iterations of an outer Loop multiplies your QPS. Tune the outer loop concurrency or add a small date
addpause inside the branch. - Partial failures - by default, one failing branch can fail the whole Parallel node. Add per-branch error handling so the merge step gets a safe default for missing data.
- Bloated state - if each branch returns megabytes of raw response, the merged record gets unwieldy. Project to the fields you actually need inside each branch.
Testing
Trigger the workflow with a customer that you know has data in every source. Inspect the execution log's branch panes individually - each should show its own input, output, and timing. Then run it with an edge-case customer (no orders, no Klaviyo profile, no tickets) and confirm the Transform step still produces a valid record with sensible defaults rather than failing.