Fork Node

The Fork node splits your workflow into multiple parallel branches, enabling simultaneous processing for maximum performance.

Overview

Fork nodes enable:

  • True parallel execution - Branches run simultaneously
  • Workload distribution - Split data across branches
  • Multi-path processing - Different operations in parallel
  • Performance optimization - Reduce total execution time

Configuration

Branch Count

Number of parallel paths (2-10):

branches: 3  // Creates 3 parallel execution paths

Data Distribution

Broadcast (Default)

Send same data to all branches:

// Input
{ data: [1, 2, 3], config: {...} }

// Branch 1 receives: { data: [1, 2, 3], config: {...} }
// Branch 2 receives: { data: [1, 2, 3], config: {...} }
// Branch 3 receives: { data: [1, 2, 3], config: {...} }

Round Robin

Distribute array items across branches:

// Input array
[item1, item2, item3, item4, item5, item6]

// Branch 1: [item1, item4]
// Branch 2: [item2, item5]
// Branch 3: [item3, item6]

Split

Divide array into equal chunks:

// Input array
[1, 2, 3, 4, 5, 6, 7, 8, 9]

// Branch 1: [1, 2, 3]
// Branch 2: [4, 5, 6]
// Branch 3: [7, 8, 9]

Custom Distribution

Use Code node before Fork for custom logic:

return {
  branch1Data: input.premiumCustomers,
  branch2Data: input.regularCustomers,
  branch3Data: input.newCustomers
};

Parallel Processing Patterns

Different Operations Same Data

Process same input through different pipelines:

        ┌→ Agent (Sentiment Analysis)
Fork ───├→ Agent (Category Classification)
        └→ Agent (Summary Generation)
                      ↓
                    Join

Load Balancing

Distribute workload across branches:

        ┌→ Process Items 1-100
Fork ───├→ Process Items 101-200
        └→ Process Items 201-300
                      ↓
                    Join (Merge Results)

Multi-API Aggregation

Call multiple APIs simultaneously:

        ┌→ Plugin (Weather API)
Fork ───├→ Plugin (News API)
        └→ Plugin (Stock API)
                      ↓
                    Join (Combine Data)

Redundancy & Fallback

Try multiple approaches:

        ┌→ Primary Service
Fork ───├→ Backup Service
        └→ Cache Lookup
                      ↓
                    Join (First Success)

Working with Branches

Branch Identification

Each branch receives metadata:

{
  branchId: 1,        // Branch number (1-based)
  totalBranches: 3,   // Total branch count
  data: {...}         // Branch-specific data
}

Branch-Specific Logic

Use Condition nodes in branches:

// Branch 1: Premium processing
input.branchId === 1 && input.customerTier === 'premium'

// Branch 2: Standard processing
input.branchId === 2

Performance Benefits

Time Comparison

Sequential Processing:

Task A (3s) → Task B (3s) → Task C (3s) = 9 seconds total

Parallel with Fork:

        ┌→ Task A (3s) ┐
Fork ───├→ Task B (3s) ├→ Join = 3 seconds total
        └→ Task C (3s) ┘

Real-World Example

// Processing 1000 items
// Sequential: 1000 × 0.5s = 500 seconds

// Parallel (10 branches): 100 items each
// Time: 100 × 0.5s = 50 seconds (10x faster!)

Use Cases

Data Enrichment

Customer Data → Fork
        ├→ Fetch Social Media
        ├→ Fetch Purchase History
        ├→ Fetch Support Tickets
        └→ Calculate Risk Score
              ↓
            Join → Enriched Profile

Multi-Model AI Processing

Text Input → Fork
        ├→ GPT-4 Analysis
        ├→ Claude Summary
        └→ Local Model Classification
              ↓
            Join → Combined Insights

Report Generation

Parameters → Fork
        ├→ Sales Report Section
        ├→ Marketing Report Section
        ├→ Operations Report Section
        └→ Finance Report Section
              ↓
            Join → Complete Report

Batch Processing

10,000 Records → Fork (10 branches)
        ├→ Process 1-1000
        ├→ Process 1001-2000
        ├→ ...
        └→ Process 9001-10000
              ↓
            Join → All Processed

Integration with Join Node

Fork nodes must connect to Join nodes:

Fork → [Parallel Processing] → Join

The Join node:

  • Waits for all branches to complete
  • Aggregates results
  • Continues workflow

Advanced Techniques

Dynamic Branch Count

Use Code node to determine branches:

// Before Fork
const itemCount = input.items.length;
const optimal = Math.min(10, Math.ceil(itemCount / 100));
return {
  ...input,
  recommendedBranches: optimal
};

Conditional Branching

Skip branches based on conditions:

// In each branch: Condition node
// Branch 1: Only process if has data
input.branch1Data && input.branch1Data.length > 0

Error Isolation

Handle failures per branch:

// Each branch: Try-catch
try {
  // Process branch data
  return { success: true, data: processed };
} catch (error) {
  return { success: false, branch: input.branchId, error };
}

Resource Optimization

// Configuration
{
  branches: 5,
  maxConcurrent: 3,  // Limit simultaneous execution
  priority: [1, 2, 3, 4, 5]  // Branch execution order
}

Best Practices

1. Right-Size Branches

// Too few: Underutilized parallelism
branches: 2  // Could be faster

// Too many: Overhead and resource strain
branches: 50  // Diminishing returns

// Just right: Based on workload
branches: Math.ceil(items.length / 100)

2. Balance Workload

// Ensure even distribution
const chunkSize = Math.ceil(items.length / branchCount);
const balanced = chunk(items, chunkSize);

3. Handle Partial Failures

// In Join node
const successful = input.filter(r => r.success);
const failed = input.filter(r => !r.success);

if (failed.length > 0) {
  // Decide: Retry? Continue? Fail?
}

4. Monitor Performance

// Log timing per branch
console.log(`Branch ${branchId} completed in ${Date.now() - start}ms`);

Common Patterns

Map-Reduce Pattern

Data → Fork (Map)
        ├→ Transform
        ├→ Transform
        └→ Transform
              ↓
         Join (Reduce) → Aggregated Result

Scatter-Gather

Request → Fork (Scatter)
        ├→ Service A
        ├→ Service B
        └→ Service C
              ↓
         Join (Gather) → Combined Response

Pipeline Parallelism

Input → Fork
        ├→ Stage 1A → Stage 2A → Stage 3A
        ├→ Stage 1B → Stage 2B → Stage 3B
        └→ Stage 1C → Stage 2C → Stage 3C
                            ↓
                          Join

Troubleshooting

"Branch timeout"

  • Reduce workload per branch
  • Increase timeout limits
  • Check for blocking operations

"Memory exceeded"

  • Reduce data per branch
  • Process in smaller chunks
  • Clear intermediate results

"Uneven completion times"

  • Better workload distribution
  • Check for slow operations
  • Consider dynamic rebalancing

"Join node waiting forever"

  • Ensure all branches connect to Join
  • Check for branch failures
  • Verify no infinite loops

Examples

Parallel API Enrichment

// Fork: 3 branches for different APIs
// Branch 1: Weather data
const weather = await fetch(`/api/weather?city=${input.city}`);

// Branch 2: Demographics
const demographics = await fetch(`/api/demographics?city=${input.city}`);

// Branch 3: Events
const events = await fetch(`/api/events?city=${input.city}`);

// Join: Combine all data
return {
  city: input.city,
  weather: branch1.data,
  demographics: branch2.data,
  events: branch3.data
};

Bulk Image Processing

// Fork: Split 1000 images across 10 branches (100 each)
// Each branch:
input.images.forEach(image => {
  // Resize
  const resized = resize(image, 800, 600);
  // Compress
  const compressed = compress(resized, 0.8);
  // Upload
  upload(compressed);
});

Multi-Strategy Analysis

// Fork: 3 different analysis methods
// Branch 1: Statistical analysis
// Branch 2: Machine learning prediction
// Branch 3: Rule-based evaluation

// Join: Vote on best result
const results = [branch1, branch2, branch3];
const winner = results.sort((a, b) => b.confidence - a.confidence)[0];

Related Topics