Introduction
Once you’ve mastered basic n8n workflows, you’ll encounter scenarios requiring more sophisticated patterns: handling errors gracefully, processing large datasets, creating reusable components, and managing complex branching logic. This guide covers advanced workflow patterns that will help you build robust, maintainable automations.
Understanding Flow Logic in n8n
n8n provides several core nodes for controlling workflow execution flow:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ n8n Flow Control Nodes โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โ If โ โ Switch โ โ Loop โ โ Wait โ โ
โ โ โ โ โ โ โ โ โ โ
โ โ Conditionโ โ Multipleโ โ Iterate โ โ Pause โ โ
โ โ Branchingโ โ Cases โ โ Items โ โ Workflowโ โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โ Merge โ โ Split โ โ Error โ โ Sub- โ โ
โ โ โ โ Batches โ โ Handler โ โ Workflowโ โ
โ โ Combine โ โ Chunk โ โ Catch โ โ Reuse โ โ
โ โ Branchesโ โ Data โ โ Errors โ โ Logic โ โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Conditional Branching
Using the If Node
The If node routes data based on conditions:
โโโโโโโโโโโโโโโโโโโ
โ Trigger โ
โ (HTTP/Webhook)โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ If โ
โ โ
โ Condition: โ
โ {{ $json.status โ
โ === "active" โ
โ }} โ
โโโโโโโโโโฌโโโโโโโโโ
โโโโโโดโโโโโ
โ โ
โผ โผ
โโโโโโโโโโ โโโโโโโโโโ
โ True โ โ False โ
โ โ โ โ
โ Processโ โ Log & โ
โ Active โ โ Return โ
โ User โ โ 400 โ
โโโโโโโโโโ โโโโโโโโโโ
Multiple Conditions
Chain If nodes for complex logic:
# Multiple If Nodes Pattern
workflow:
- If: "status === 'active'" # First check
true: โ Check Permission
false: โ Log Inactive User
- If: "role === 'admin'" # Second check
true: โ Full Access
false: โ Limited Access
Using the Switch Node
For multiple branches, Switch is more efficient:
# Switch Node Configuration
{
"data": "{{ $json.order_status }}",
"cases": {
"pending": "โ Process Pending Orders",
"processing": "โ Update Processing Status",
"shipped": "โ Send Shipping Notification",
"delivered": "โ Update CRM",
"_default": "โ Log Unknown Status"
}
}
Looping and Iteration
Split In Batches Node
Process large datasets without overwhelming APIs:
โโโโโโโโโโโโโโโโโโโ
โ Get All Items โ
โ (1000+ records)โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ Split In Batchesโ
โ โ
โ Batch Size: 10 โ
โ Wait: 500ms โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โโโโโโดโโโโโ
โ Loop โ
โ 10 at โ
โ a time โ
โผ โผ
โโโโโโโโโโโโโโโโโโโ
โ Process Each โ
โ Batch of 10 โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ Continue โ
โ Loop? โ
โโโโโโโโโโโโโโโโโโโ
Loop Over Items Configuration
// Loop configuration
{
"batchSize": 10, // Items per iteration
"wait": 500, // Wait between batches (ms)
"maxWait": 30000 // Maximum wait time
}
Practical Example: Process Customer List
# Customer Processing Workflow
1. Trigger: Schedule (daily at 9 AM)
2. HTTP Request: GET /api/customers
3. Split In Batches:
- Batch size: 5
- Wait: 1000ms (rate limiting)
4. Loop per batch:
a. HTTP Request: POST /api/send-email (per customer)
b. Wait: 500ms
5. Slack: Send summary message
Error Handling
Error Workflow Pattern
Create a dedicated error handling workflow:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Main Workflow โ
โ โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โ Execute โโโโโบโ Execute โโโโโบโ Success โ โ
โ โ Step 1 โ โ Step 2 โ โ Action โ โ
โ โโโโโโโโโโโ โโโโโโฌโโโโโ โโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโดโโโโโโโ โ
โ โ Error? โ โ
โ โโโโโโโโฌโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโ โ
โ โ Continue: โ โ
โ โ Error Workflow โ โ
โ โโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Error Trigger Node
# Error Workflow Setup
1. Error Trigger Node
- Trigger on: Any Workflow Error
- Include: Full error details
2. Notify Team (Slack/Email)
- Subject: "n8n Workflow Error: {{$json.workflow.name}}"
- Message: "{{$json.execution.error.message}}"
3. Log to Database
- Table: error_logs
- Fields: workflow_id, error_message, timestamp, data
4. Auto-Retry (optional)
- Retry failed execution
Retry Pattern with Error Handling
// Using Error Workflow with Retry
{
"errorWorkflow": "error-handler-main", // Separate error workflow
"continueOnFail": true, // Continue on failure
"retryOnFail": true, // Enable retry
"maxTries": 3, // Max 3 attempts
"wait": 5000 // Wait 5 seconds between tries
}
Good vs Bad Error Handling
// BAD: No error handling
async function badWorkflow() {
const data = await httpRequest();
await processData(data);
await sendNotification();
// If any step fails, entire workflow stops silently
}
// GOOD: Proper error handling
async function goodWorkflow() {
try {
const data = await httpRequest();
await processData(data);
await sendNotification();
} catch (error) {
// Log error details
await logError(error);
// Notify team
await notifyTeam(error);
// Optionally retry
await retryWorkflow();
}
}
Parallel Execution
Running Tasks Concurrently
โโโโโโโโโโโโโโโโโโโ
โ Trigger โ
โโโโโโโโโโฌโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Fork Flow โ
โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโ โ
โ โ Fetch โ โ Fetch โ โFetch โ โ
โ โ Orders โ โ Customersโ โProductsโ โ
โ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โโโโฌโโโโโ โ
โ โ โ โ โ
โ โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโ โ
โ โผ โ
โ โโโโโโโโโโโโโโโ โ
โ โ Merge Data โ โ
โ โ (Join All) โ โ
โ โโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Merge Node Configuration
# Merge Node Options
mergeMode: "manual" # or "pass-through"
joinMode: "inner" # inner, outer, left, right
overlapMode: "prefer1" # prefer1, prefer2, preferBoth
Performance Comparison
| Pattern | Time (100 items) | API Calls |
|---|---|---|
| Sequential | 100 seconds | 100 |
| Parallel (10 concurrent) | 10 seconds | 100 |
| Split in Batches (10) | 11 seconds | 110 |
Sub-workflows
Creating Reusable Workflows
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Main Workflow โ
โ โ
โ 1. Trigger (Schedule) โ
โ 2. Get Data โ
โ 3. Execute Sub-workflow โ
โ โ Transform Data (reusable) โ
โ 4. Save Results โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Sub-workflow: Transform Data โ
โ โ
โ 1. Trigger: Workflow Call โ
โ 2. Edit Fields (Set) โ
โ 3. Rename Keys โ
โ 4. Return Data โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Execute Workflow Node
# Call sub-workflow
{
"workflowId": "workflow_id_here",
"data": {
"input": "{{ $json.data }}",
"mode": "transform"
},
"waitForResponse": true
}
Benefits of Sub-workflows
- Reusability: Use same logic across multiple workflows
- Maintainability: Update in one place
- Testing: Test sub-workflows independently
- Organization: Cleaner main workflows
Waiting and Delays
Wait Node Patterns
# Delayed Processing
1. Receive Order
2. Wait: 24 hours
3. Check Order Status
4. If pending โ Send Reminder
# Approval Workflow
1. Receive Request
2. Send Approval Request (Slack)
3. Wait: 48 hours for response
4. Check: Approval Received?
- Yes โ Process Request
- No โ Escalate or Cancel
Wait Node Configuration
{
"amount": 24, // Wait duration
"unit": "hours", // seconds, minutes, hours, days
"addTimestamp": true // Add wait metadata
}
Combining Patterns
Complete Example: Order Processing Pipeline
# Complete Workflow
1. Webhook Trigger (new order received)
2. Split In Batches (process items)
- Batch size: 5
3. Loop per batch:
a. If item in stock:
- Reserve inventory โ
b. If item out of stock:
- Continue on fail: true
- Log to "backorder" table
4. Merge results
5. If all items available:
- Calculate shipping
- Create shipment
- Send confirmation email
6. If some items backordered:
- Send partial fulfillment email
- Create follow-up task
7. Error Workflow:
- Log to database
- Send Slack notification
- Retry up to 3 times
Best Practices
Good Patterns
# Good: Clear error handling
- name: "API Call with Error Handling"
nodes:
- HTTP Request
- Error Workflow: "notify-team-on-fail"
- Continue on Fail: false
# Good: Rate limiting
- Split In Batches
batchSize: 10
wait: 1000
# Good: Idempotent operations
- Check if record exists before creating
- Use unique identifiers
Bad Patterns to Avoid
# Bad: No rate limiting
- HTTP Request (1000 calls at once)
# Results: API blocking, IP ban
# Bad: Swallowed errors
- Continue on Fail: true (everywhere)
# Results: Silent failures, data loss
# Bad: Deep nesting
- 10+ levels of If nodes
# Results: Unmaintainable
Debugging Complex Workflows
Using Debug Tools
# Add debug points
1. NoOp (Debug Helper)
- Input: "{{ $json }}"
2. Edit Fields (Debug)
- Add: "{{ $now }}" timestamp
- Add: "{{ $execution.id }}"
3. Filter (for testing)
- Condition: "{{ $json.test === true }}"
Execution Analysis
- Use “All Executions” view to see history
- Check execution time for bottlenecks
- Monitor data transformation at each step
Conclusion
Mastering these advanced patterns will help you build robust, scalable n8n workflows. Start with simple patterns and gradually incorporate more complexity as needed. Remember:
- Always implement error handling from the start
- Use sub-workflows for reusable logic
- Monitor and log everything in production
- Test thoroughly before deploying
Related Articles
- n8n Complete Guide: AI-Powered Workflow Automation
- n8n Self-Hosted Production Guide
- n8n Webhooks and API Integration
Comments