Parallel Node

Overview

The Parallel node executes multiple branches simultaneously, allowing independent operations to run concurrently. The workflow continues only after all branches have completed successfully.

When to Use

Use a Parallel node when you need to:

  • Execute independent operations simultaneously
  • Perform multiple API calls at once
  • Process different data sources concurrently
  • Run validations in parallel
  • Speed up workflow execution by avoiding sequential bottlenecks
  • Collect data from multiple sources before proceeding

Configuration

Branches

Each branch represents an independent execution path that runs in parallel:

  • Name: Descriptive name for the branch
  • Nodes: The workflow nodes that execute in this branch
  • First Node: The starting node in this branch

You must define at least 2 branches (minimum requirement for parallel execution).

Branch Configuration

Configure each branch by:

  1. Naming the branch to describe its purpose
  2. Adding nodes to the branch in the workflow editor
  3. Connecting nodes within the branch

Each branch executes independently until completion.

How It Works

  1. Concurrent Execution: All branches start at the same time
  2. Independent Progress: Each branch executes its nodes without waiting for other branches
  3. Wait for All: The workflow waits for all branches to complete
  4. Collect Results: Results from all branches are available after completion
  5. Continue: The workflow proceeds to onSuccess only when all branches finish

If any branch fails:

  • The parallel node fails
  • The onFailure path is followed (if defined)
  • Other branches may continue executing but their results are discarded

Examples

Example: Multiple API Calls

Node ID: fetchUserData

Branch 1: “Profile”

  • getUserProfile - Fetches user profile from API

Branch 2: “Orders”

  • getUserOrders - Fetches user’s order history

Branch 3: “Preferences”

  • getUserPreferences - Fetches user preferences

All three API calls happen simultaneously. Access results:

$.results.getUserProfile.profile
$.results.getUserOrders.orders
$.results.getUserPreferences.settings

Example: Data Validation

Node ID: validateSubmission

Branch 1: “Email Validation”

  • checkEmailFormat - Validates email syntax
  • checkEmailDomain - Verifies domain exists

Branch 2: “Phone Validation”

  • checkPhoneFormat - Validates phone format
  • checkPhoneCarrier - Verifies carrier

Branch 3: “Address Validation”

  • normalizeAddress - Standardizes address format
  • validateAddress - Verifies address with Google Maps

All validations run in parallel, reducing total execution time.

Example: Enrichment Pipeline

Node ID: enrichLead

Branch 1: “Company Data”

  • lookupCompany - Gets company information
  • getCompanySize - Determines employee count

Branch 2: “Social Profiles”

  • findLinkedIn - Searches for LinkedIn profile
  • findTwitter - Searches for Twitter profile

Branch 3: “Email Verification”

  • verifyEmail - Checks if email exists
  • checkSpamScore - Verifies email quality

After all branches complete, you have enriched lead data from multiple sources.

Example: Multi-Channel Notification

Node ID: notifyUser

Branch 1: “Email”

  • formatEmailMessage - Creates email body
  • sendEmail - Sends via email service

Branch 2: “SMS”

  • formatSMSMessage - Creates SMS body
  • sendSMS - Sends via SMS service

Branch 3: “Push Notification”

  • formatPushMessage - Creates push notification
  • sendPush - Sends via push service

User receives all notifications simultaneously.

Accessing Branch Results

Each branch’s nodes produce their own results accessible via JSONPath:

// Branch 1 results
$.results.<branch1NodeId>.field

// Branch 2 results
$.results.<branch2NodeId>.field

// Branch 3 results
$.results.<branch3NodeId>.field

Example Access Pattern

After parallel node fetchAllData with three branches:

// From profile branch
$.results.getProfile.name
$.results.getProfile.email

// From orders branch
$.results.getOrders.items
$.results.getOrders.total

// From analytics branch
$.results.getAnalytics.pageviews
$.results.getAnalytics.conversions

Best Practices

  • Independent Branches: Ensure branches don’t depend on each other’s results
  • Similar Duration: Try to balance branch execution times
  • Error Handling: Set onFailure paths on the parallel node for branch failures
  • Resource Limits: Be aware of API rate limits when making parallel calls
  • Naming: Use clear, descriptive names for branches
  • Minimize Branches: Only parallelize truly independent operations
  • Test Individually: Verify each branch works correctly before parallel execution

Common Patterns

Fan-Out Data Processing

Parallel: processData
├─ Branch 1: Transform
│  └─ transformData → validateTransform
├─ Branch 2: Analyze
│  └─ analyzeData → generateInsights
└─ Branch 3: Store
   └─ saveToDatabase → confirmSaved

Multi-Source Data Collection

Parallel: gatherData
├─ Branch 1: Internal API
│  └─ callInternalAPI → parseResponse
├─ Branch 2: External API
│  └─ callExternalAPI → parseResponse
└─ Branch 3: Database
   └─ queryDatabase → formatResults

Parallel Validations

Parallel: validateAll
├─ Branch 1: Schema
│  └─ validateSchema
├─ Branch 2: Business Rules
│  └─ validateBusinessRules
└─ Branch 3: External Check
   └─ callValidationService

Multi-Step Enrichment

Parallel: enrichData
├─ Branch 1: Geographic
│  └─ geocodeAddress → getTimezone
├─ Branch 2: Demographic
│  └─ lookupDemographics → scoreLead
└─ Branch 3: Financial
   └─ checkCreditScore → assessRisk

Limitations

  • Minimum Branches: Requires at least 2 branches
  • All Must Succeed: If any branch fails, the entire parallel node fails
  • No Partial Results: Cannot proceed with partial results if one branch fails
  • Resource Usage: Multiple concurrent operations consume more resources
  • No Branch Communication: Branches cannot share data during execution
  • Sequential Within Branch: Nodes within each branch still execute sequentially

Error Handling

Branch Failure

If a node in any branch fails:

  • The parallel node immediately fails
  • The onFailure path is triggered
  • Other branches may continue but results are discarded

Handling Failures

Set onFailure on the parallel node:

Parallel: fetchData
  onFailure: handleDataFetchError

Or handle errors within branches using conditional nodes:

Branch 1:
  └─ callAPI
     └─ Conditional: checkSuccess
        ├─ Success → processData
        └─ Failure → returnDefaultData

Performance Considerations

  • Faster Execution: Parallel execution reduces total workflow time
  • Resource Usage: More concurrent operations require more resources
  • Rate Limits: Multiple API calls may hit rate limits faster
  • Cost: Parallel execution may increase costs for metered services
  • Timeout: Workflow waits for slowest branch to complete

Combining with Other Nodes

Parallel + Repeat

Repeat: processUsers ($.results.getUsers.users)
└─ Parallel: enrichEachUser
   ├─ Branch 1: getProfile
   ├─ Branch 2: getOrders
   └─ Branch 3: getPreferences

Parallel + Conditional

Parallel: fetchAndValidate
├─ Branch 1: fetchData
└─ Branch 2: validateCredentials

└─ Conditional: checkBothSucceeded
   ├─ Both OK → proceed
   └─ Either Failed → handleError

Nested Parallel

Parallel: outerParallel
├─ Branch 1: simpleOperation
└─ Branch 2: complexOperation
   └─ Parallel: innerParallel
      ├─ Branch A: subOperation1
      └─ Branch B: subOperation2