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
- Parallel Processing - Fork & Join patterns
- Loop Node - Sequential iteration alternative
- Parallel Processing - Design patterns