
🎓 Optimize Speed-Critical Workflows Using Parallel Processing (Fan-Out-Fan-In)
Description
Categories
🔧 Engineering🤖 AI & Machine Learning
Nodes Used
n8n-nodes-base.ifn8n-nodes-base.ifn8n-nodes-base.setn8n-nodes-base.setn8n-nodes-base.coden8n-nodes-base.waitn8n-nodes-base.switchn8n-nodes-base.splitOutn8n-nodes-base.stickyNoten8n-nodes-base.stickyNote
PriceGratis
Views0
Last Updated11/28/2025
workflow.json
{
"meta": {
"creator": "Lucas Peyrin",
"instanceId": "e409ea34548a2afe2dffba31130cd1cf2e98ebe2afaeed2a63caf2a0582d1da0",
"fingerprint": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjcmVhdG9yIjoiIiwiaXNzIjoibjhuIiwiaWF0IjoxNzUzMTQ0MDU0fQ.wnimKzcmWe7ihoVF2LKDp24GNwgHh-nFEGhNJd1iP_s",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "a514f04d-0f18-4016-bb0f-20f598210dff",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Start Project",
"type": "n8n-nodes-base.manualTrigger",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-784,
-1184
],
"parameters": {},
"typeVersion": 1
},
{
"id": "3fac5b1b-d94c-4b0a-a3d2-3edf5fd2934b",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "The Dispatcher",
"type": "n8n-nodes-base.switch",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
16,
-384
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "write_description",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9ba4d141-2f64-4b74-8e72-a3da836e3f8f",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.process }}",
"rightValue": "write_description"
}
]
},
"renameOutput": true
},
{
"outputKey": "write_ad_copy",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "88b909d3-9bc2-4ae8-841d-58b88df591ef",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.process }}",
"rightValue": "write_ad_copy"
}
]
},
"renameOutput": true
},
{
"outputKey": "write_email",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "664df8e3-81f2-43e6-b852-c02693fa6ef2",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.process }}",
"rightValue": "write_email"
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "58e0764e-1d4a-4ff3-9274-1943ad2b6645",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Split Out Tasks",
"type": "n8n-nodes-base.splitOut",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-224,
-1184
],
"parameters": {
"options": {},
"fieldToSplitOut": "tasks"
},
"typeVersion": 1
},
{
"id": "da60465a-b7b4-4746-a9a5-c4bca8e66a78",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "The Project Brief",
"type": "n8n-nodes-base.set",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-448,
-1184
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "550d27f1-bb91-4290-ab17-f055d08920be",
"name": "tasks",
"type": "array",
"value": "=[{\"process\":\"write_description\",\"data\":{\"product\":\"Super Widget\"}},{\"process\":\"write_ad_copy\",\"data\":{\"product\":\"Super Widget\",\"tone\":\"Excited\"}},{\"process\":\"write_email\",\"data\":{\"product\":\"Super Widget\",\"audience\":\"Tech CEOs\"}}]"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "4145b00b-b9f5-4573-a44b-529709d9de61",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Wait for All Teams to Finish",
"type": "n8n-nodes-base.wait",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
592,
-1184
],
"webhookId": "834824f3-7ace-4224-bb60-53ff8f12e89d",
"parameters": {
"resume": "webhook",
"options": {},
"httpMethod": "POST"
},
"executeOnce": true,
"typeVersion": 1.1
},
{
"id": "6edc8c72-8372-4a4f-9698-f5279c90663e",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Assign Tasks to Teams",
"type": "n8n-nodes-base.executeWorkflow",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
128,
-1184
],
"parameters": {
"options": {
"waitForSubWorkflow": false
},
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $workflow.id }}"
},
"workflowInputs": {
"value": {
"data": "={{ $json.data }}",
"status": "initialise",
"process": "={{ $json.process }}",
"resume_url": "={{ $execution.resumeUrl }}",
"main_execution_id": "={{ $execution.id }}"
},
"schema": [
{
"id": "main_execution_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "main_execution_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "process",
"type": "string",
"display": true,
"required": false,
"displayName": "process",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "data",
"type": "object",
"display": true,
"required": false,
"displayName": "data",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "resume_url",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "resume_url",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": true
}
},
"typeVersion": 1.2,
"alwaysOutputData": true
},
{
"id": "5493e3ed-ae58-48df-8315-cf4599525b7a",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Receive Work Order",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-432,
-176
],
"parameters": {
"workflowInputs": {
"values": [
{
"name": "main_execution_id"
},
{
"name": "process"
},
{
"name": "data",
"type": "object"
},
{
"name": "status"
},
{
"name": "resume_url"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "11b9ba94-349b-4af2-921e-b1933cc2b9b6",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "The AI Specialist",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
416,
0
],
"parameters": {
"options": {
"temperature": 0
}
},
"credentials": {
"googlePalmApi": {
"id": "AXawYbABK5aZbGBE",
"name": "IA2S"
}
},
"typeVersion": 1
},
{
"id": "0d9fb81e-a2ca-40e6-841a-bf0341b4b902",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Description Team",
"type": "@n8n/n8n-nodes-langchain.agent",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
320,
-560
],
"parameters": {
"text": "=Write a product description for: {{$json.data.product}}",
"options": {
"systemMessage": "No preamble. Just what you're asked for."
},
"promptType": "define"
},
"typeVersion": 2.1
},
{
"id": "b6ebf60e-dcff-4f6c-aefc-8bd1bc65c848",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Ad Copy Team",
"type": "@n8n/n8n-nodes-langchain.agent",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
320,
-368
],
"parameters": {
"text": "=Write ad copy for: {{$json.data.product}}. The tone should be: {{$json.data.tone}}",
"options": {
"systemMessage": "No preamble. Just what you're asked for."
},
"promptType": "define"
},
"typeVersion": 2.1
},
{
"id": "f2029b42-6a36-4220-bc4f-8c8b12dcb977",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Email Team",
"type": "@n8n/n8n-nodes-langchain.agent",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
320,
-176
],
"parameters": {
"text": "=Write a cold email about {{$json.data.product}} for the following audience: {{$json.data.audience}}",
"options": {
"systemMessage": "No preamble. Just what you're asked for."
},
"promptType": "define"
},
"typeVersion": 2.1
},
{
"id": "41ddaf46-6e78-4463-9454-0bc6aa9c6075",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Report Back to Manager",
"type": "n8n-nodes-base.executeWorkflow",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
784,
-368
],
"parameters": {
"mode": "each",
"options": {
"waitForSubWorkflow": false
},
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $workflow.id }}"
},
"workflowInputs": {
"value": {
"data": "={{ $json }}",
"status": "completed",
"process": "={{ $('Receive Work Order').last().json.process }}",
"main_execution_id": "={{ $('Receive Work Order').last().json.main_execution_id }}"
},
"schema": [
{
"id": "main_execution_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "main_execution_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "process",
"type": "string",
"display": true,
"required": false,
"displayName": "process",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "data",
"type": "object",
"display": true,
"required": false,
"displayName": "data",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "resume_url",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "resume_url",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": true
}
},
"typeVersion": 1.2
},
{
"id": "b54e5478-9723-48ef-94aa-563726294d3b",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-544,
-1520
],
"parameters": {
"color": 7,
"width": 1904,
"height": 544,
"content": "## The Main Workflow (The Project Manager)\n\nThis top flow is the **Project Manager**. Its only job is to start the project, assign the tasks, and wait for all the teams to report back that their work is complete."
},
"typeVersion": 1
},
{
"id": "07aa4fd8-fa34-481a-8735-c21b0a5458dd",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-544,
-944
],
"parameters": {
"color": 7,
"width": 1600,
"height": 1680,
"content": "## The Sub-Workflow (The Specialist Teams)\n\nThis bottom flow represents the **Specialist Teams**. It receives a single work order, does the job, and reports its status back to the Project Dashboard."
},
"typeVersion": 1
},
{
"id": "b454585f-b383-4b60-8766-6f114aee7baf",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "The Project Dashboard (Code)",
"type": "n8n-nodes-base.code",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
16,
352
],
"parameters": {
"jsCode": "// This node is the brain of the whole operation.\n// It uses Static Data, which is like a shared whiteboard for the workflow.\n\n// Get the shared whiteboard data.\nconst staticData = $getWorkflowStaticData('global');\nif (!staticData.projects) {\n staticData.projects = {};\n}\n\n// Get the status from the incoming item.\nconst status = $json.status;\n\n// --- CASE 1: A new project is starting --- //\nif (status === 'initialise') {\n const mainId = $json.main_execution_id;\n const resumeUrl = $json.resume_url;\n const tasksToRun = $input.all();\n\n // Create a new section on our dashboard for this project.\n staticData.projects[mainId] = {\n resumeUrl: resumeUrl,\n tasks: {}\n };\n\n // Add each task to the dashboard with a 'pending' status and start time.\n for (const task of tasksToRun) {\n const processName = task.json.process;\n staticData.projects[mainId].tasks[processName] = {\n status: 'pending',\n startTime: new Date().toISOString()\n };\n }\n console.log(`Project ${mainId} initialized with ${tasksToRun.length} tasks.`);\n\n // Send the tasks out to the specialist teams.\n return tasksToRun;\n}\n\n// --- CASE 2: A specialist team has finished a task --- //\nif (status === 'completed') {\n const mainId = $json.main_execution_id;\n const completedProcess = $json.process;\n const resultData = $json.data;\n const projectDashboard = staticData.projects[mainId];\n\n if (!projectDashboard) {\n console.log(`No dashboard found for mainId: ${mainId}.`);\n return []; // Stop if the project doesn't exist.\n }\n\n // Update the task on the dashboard.\n const task = projectDashboard.tasks[completedProcess];\n task.status = 'completed';\n task.endTime = new Date().toISOString();\n task.result = resultData;\n // Calculate duration in seconds\n const durationMs = new Date(task.endTime) - new Date(task.startTime);\n task.duration_seconds = parseFloat((durationMs / 1000).toFixed(2));\n\n console.log(`Task ${completedProcess} for project ${mainId} marked as completed in ${task.duration_seconds}s.`);\n\n // Check if ALL tasks on the dashboard are now 'completed'.\n const allDone = Object.values(projectDashboard.tasks).every(t => t.status === 'completed');\n\n if (allDone) {\n console.log(`All tasks for project ${mainId} are done. Resuming main workflow.`);\n const resumeUrl = projectDashboard.resumeUrl;\n const finalResponse = projectDashboard.tasks;\n\n // Clean up the dashboard for this project.\n delete staticData.projects[mainId];\n\n // Return a special item that will trigger the 'Resume Parent Workflow' node.\n return [{\n json: {\n end_process: true,\n resume_url: resumeUrl,\n response: finalResponse\n }\n }];\n }\n\n // If not all tasks are done, we do nothing and wait for the next team to report back.\n return [];\n}\n\n// By default, if the status is not 'initialise' or 'completed', do nothing.\nreturn [];"
},
"typeVersion": 2
},
{
"id": "7f8dde47-d0d1-4a6d-8835-747acfead126",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Start Process",
"type": "n8n-nodes-base.executeWorkflow",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
816,
528
],
"parameters": {
"mode": "each",
"options": {
"waitForSubWorkflow": false
},
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $workflow.id }}"
},
"workflowInputs": {
"value": {
"data": "={{ $json.data }}",
"status": "pending",
"process": "={{ $json.process }}",
"main_execution_id": "={{ $json.main_execution_id }}"
},
"schema": [
{
"id": "main_execution_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "main_execution_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "process",
"type": "string",
"display": true,
"required": false,
"displayName": "process",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "data",
"type": "object",
"display": true,
"required": false,
"displayName": "data",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": true
}
},
"typeVersion": 1.2
},
{
"id": "5d738915-c7aa-476c-ac3f-2db43c55848a",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Check Work Order Status",
"type": "n8n-nodes-base.if",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-208,
-176
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "bed89853-0399-4038-8650-5d578d34e5fb",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "pending"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "c44019a3-fd3a-4c75-9dcb-18f46da0f84a",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Is Project Complete?",
"type": "n8n-nodes-base.if",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
416,
352
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "aab184da-7adb-4008-9ccd-99152b55e837",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.end_process }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "a05d0e03-c51a-4bfd-ac45-d285f17d7696",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Resume Parent Workflow",
"type": "n8n-nodes-base.httpRequest",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
816,
144
],
"parameters": {
"url": "={{ $json.resume_url }}",
"method": "POST",
"options": {},
"jsonBody": "={{ $json.response }}",
"sendBody": true,
"specifyBody": "json"
},
"typeVersion": 4.2
},
{
"id": "8dab80dc-6ea8-47b1-bfde-546cd6a853a5",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Project Complete!",
"type": "n8n-nodes-base.set",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
1056,
-1184
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c8f45ef6-748c-42e0-937b-48766f039259",
"name": "email",
"type": "string",
"value": "={{ $json.body.write_email.result.output }}"
},
{
"id": "c3db0b0f-86c6-4de3-980d-f3d8570b132b",
"name": "ad_copy",
"type": "string",
"value": "={{ $json.body.write_ad_copy.result.output }}"
},
{
"id": "d6894be9-9835-41dd-8cec-e40044b84d2e",
"name": "description",
"type": "string",
"value": "={{ $json.body.write_description.result.output }}"
},
{
"id": "e7f8a9b0-c1d2-e3f4-a5b6-c7d8e9f0a1b2",
"name": "seconds_saved",
"type": "number",
"value": "={{ $json.body.values().map(item => item.duration_seconds).sum() - $json.body.values().map(item => item.duration_seconds).max() }}"
},
{
"id": "5477e4af-b915-4129-b573-5c35ea15aa08",
"name": "task_duration_seconds",
"type": "number",
"value": "={{ $json.body.values().map(item => item.duration_seconds).max() }}"
},
{
"id": "bb5305a7-1d69-4d68-8610-500e19a947e4",
"name": "task_duration_without_parallelisation",
"type": "number",
"value": "={{ $json.body.values().map(item => item.duration_seconds).sum() }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "8ca34e6a-bfe6-4fbd-8744-c8b7d00e9c56",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-512,
-1408
],
"parameters": {
"color": 7,
"width": 448,
"height": 400,
"content": "### The Project Brief\n\nThis node defines all the independent tasks we need to accomplish for this project. Each task has a `process` name and the `data` it needs."
},
"typeVersion": 1
},
{
"id": "c76dcf95-13a2-45e5-961f-1342e33aec62",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-48,
-1408
],
"parameters": {
"color": 7,
"width": 448,
"height": 400,
"content": "### Assign Tasks (Fan-Out)\n\nThis is the **Fan-Out** moment. This node calls our sub-workflow for each task.\n\n**Crucial Setting:** `Wait for Sub-Workflow` is **OFF**. This means the main workflow doesn't wait. It fires off all the tasks and immediately moves to the `Wait` node."
},
"typeVersion": 1
},
{
"id": "da5e23d0-9167-4ac9-9c76-c81f6e492bd3",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
416,
-1408
],
"parameters": {
"color": 7,
"width": 448,
"height": 400,
"content": "### Wait for Completion (Pause)\n\nThis node **pauses** the main workflow indefinitely. It's the Project Manager waiting in their office.\n\nIt will only resume when another node (in our case, the `Resume Parent Workflow` node) makes a `POST` request to its unique `resume_url`."
},
"typeVersion": 1
},
{
"id": "73387584-46dc-4bfb-816b-20d88a2f88a4",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
880,
-1408
],
"parameters": {
"color": 7,
"width": 448,
"height": 400,
"content": "### Project Complete! (Fan-In)\n\nThis is the **Fan-In** moment. This node only runs *after* the `Wait` node has been resumed.\n\nIt receives the final, aggregated data from all the parallel tasks and can now continue with the rest of the workflow."
},
"typeVersion": 1
},
{
"id": "27335a12-cede-465c-8b71-309d5dd5d37b",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-512,
-336
],
"parameters": {
"color": 7,
"height": 336,
"content": "### Receive Work Order\n\nThis is the entry point for the Specialist Teams. It receives a single task from the main workflow."
},
"typeVersion": 1
},
{
"id": "0f42ccf2-bdab-4882-b1c7-90d91d2f74b2",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-80,
-528
],
"parameters": {
"color": 4,
"width": 288,
"height": 336,
"content": "### The Dispatcher\n\nThis Switch node acts as a dispatcher, sending the work order to the correct Specialist Team based on the `process` name."
},
"typeVersion": 1
},
{
"id": "6d1b4c86-c663-4420-a2da-60e4fc87ddab",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
256,
-720
],
"parameters": {
"color": 7,
"width": 416,
"height": 848,
"content": "### The Specialist Teams\n\nThese three Agent nodes represent the different teams doing the actual work. In a real-world scenario, these could be complex sub-workflows themselves."
},
"typeVersion": 1
},
{
"id": "c82f2081-50a5-488c-bbde-d59c5adcb2bc",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
688,
-576
],
"parameters": {
"color": 7,
"width": 288,
"height": 384,
"content": "### Report Back to Manager\n\nThis node doesn't talk to the main workflow directly. Instead, it calls the sub-workflow *again*, but this time with a `status` of `completed`. This is the signal for the Project Dashboard to update."
},
"typeVersion": 1
},
{
"id": "a7841998-7c67-448c-8c98-c94e851402c7",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note14",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-256,
32
],
"parameters": {
"color": 6,
"width": 480,
"height": 512,
"content": "### The Project Dashboard (Code)\n\nThis is the most important node. It acts as the central brain and state manager for the entire operation, using **Static Data** as a shared whiteboard.\n\nIt handles two cases:\n1. **`status: 'initialise'`:** When a new project starts, it creates a new entry on the dashboard and lists all tasks as 'pending'.\n2. **`status: 'completed'`:** When a team reports back, it updates that task's status on the dashboard. It then checks if *all* tasks are complete. If they are, it triggers the `Resume Parent Workflow` node."
},
"typeVersion": 1
},
{
"id": "a0e3bb3c-71ca-485d-8daf-67f8df6ba97d",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note15",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
704,
-64
],
"parameters": {
"color": 7,
"width": 320,
"height": 368,
"content": "### Resume Parent Workflow\n\nThis node is only triggered when the Project Dashboard confirms all tasks are complete. It makes a `POST` request to the `Wait` node's unique URL, sending the final results and waking up the main workflow."
},
"typeVersion": 1
},
{
"id": "410c8b95-c5fc-4ad0-85a3-e2f647a23cd3",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note16",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-256,
-816
],
"parameters": {
"color": 4,
"width": 496,
"height": 816,
"content": "### Alternative Architecture\n\nFor even more complex projects, you could replace this Switch node with a more modular design:\n\n- Each \"Team\" (Description, Ad Copy, etc.) could be its own separate, dedicated workflow.\n- The main workflow would call the correct workflow based on the `process` name (that could be a workflow id).\n- A single, separate \"Status Handler\" workflow would manage the Project Dashboard logic, called by each team when they finish."
},
"typeVersion": 1
},
{
"id": "1d9b9fc4-d181-4555-a9c4-febf7c1fa459",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
-1152,
-1600
],
"parameters": {
"width": 576,
"height": 616,
"content": "## Tutorial: Parallel Processing (Fan-Out/Fan-In)\n\nWelcome! This template demonstrates an advanced but incredibly powerful n8n pattern for running multiple tasks **in parallel**.\n\n**When to use this?**\nWhen **speed is your top priority**. If you have multiple independent tasks (like calling an AI 3 times), running them at the same time is much faster than running them one after another.\n\n**The Analogy: A Construction Project**\n- **Main Workflow:** The **Project Manager** who starts the project and waits for it to be done.\n- **Sub-Workflow:** The **Specialist Teams** (electricians, painters) who do the actual work.\n- **Static Data:** The **Project Dashboard** where the manager tracks each team's progress."
},
"typeVersion": 1
},
{
"id": "7ad3b188-ad65-42e1-870b-ace7e61a5d9b",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
704,
320
],
"parameters": {
"color": 7,
"width": 320,
"height": 384,
"content": "### Start Specialit Teams\n\nThis node doesn't talk to the main workflow directly. Instead, it calls the sub-workflow *again*, but this time with a `status` of `pending`. This is the signal for the Teams to start. This could be replaced with calling specific sub workflows for each task."
},
"typeVersion": 1
},
{
"id": "751c86aa-9223-4431-a252-560b16c4d4c3",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"notes": "© 2025 Lucas Peyrin",
"creator": "Lucas Peyrin",
"position": [
1088,
-544
],
"parameters": {
"color": 3,
"width": 540,
"height": 1280,
"content": "## Was this helpful? Let me know!\n[](https://n8n.ac)\n\nI really hope this tutorial helped you grasp parallel processing in n8n. Your feedback is incredibly valuable and helps me create better resources for the n8n community.\n\n### **Share Your Thoughts & Ideas**\n\nWhether you have a suggestion, found a typo, or just want to say thanks, I'd love to hear from you!\nHere's a simple n8n form built for this purpose:\n\n#### ➡️ **[Click here to give feedback](https://api.ia2s.app/form/templates/feedback?template=Parallel%20Processing%20Tutorial)**\n\n### **Ready to Build Something Great?**\n\nIf you're looking to take your n8n skills or business automation to the next level, I can help.\n\n**🎓 n8n Coaching:** Want to become an n8n pro? I offer one-on-one coaching sessions to help you master workflows, tackle specific problems, and build with confidence.\n#### ➡️ **[Book a Coaching Session](https://api.ia2s.app/form/templates/coaching?template=Parallel%20Processing%20Tutorial)**\n\n**💼 n8n Consulting:** Have a complex project, an integration challenge, or need a custom workflow built for your business? Let's work together to create a powerful automation solution.\n#### ➡️ **[Inquire About Consulting Services](https://api.ia2s.app/form/templates/consulting?template=Parallel%20Processing%20Tutorial)**\n\n---\n\nHappy Automating!\nLucas Peyrin | [n8n Academy](https://n8n.ac)"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"Email Team": {
"main": [
[
{
"node": "Report Back to Manager",
"type": "main",
"index": 0
}
]
]
},
"Ad Copy Team": {
"main": [
[
{
"node": "Report Back to Manager",
"type": "main",
"index": 0
}
]
]
},
"Start Project": {
"main": [
[
{
"node": "The Project Brief",
"type": "main",
"index": 0
}
]
]
},
"The Dispatcher": {
"main": [
[
{
"node": "Description Team",
"type": "main",
"index": 0
}
],
[
{
"node": "Ad Copy Team",
"type": "main",
"index": 0
}
],
[
{
"node": "Email Team",
"type": "main",
"index": 0
}
]
]
},
"Split Out Tasks": {
"main": [
[
{
"node": "Assign Tasks to Teams",
"type": "main",
"index": 0
}
]
]
},
"Description Team": {
"main": [
[
{
"node": "Report Back to Manager",
"type": "main",
"index": 0
}
]
]
},
"The AI Specialist": {
"ai_languageModel": [
[
{
"node": "Description Team",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Ad Copy Team",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Email Team",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"The Project Brief": {
"main": [
[
{
"node": "Split Out Tasks",
"type": "main",
"index": 0
}
]
]
},
"Receive Work Order": {
"main": [
[
{
"node": "Check Work Order Status",
"type": "main",
"index": 0
}
]
]
},
"Is Project Complete?": {
"main": [
[
{
"node": "Resume Parent Workflow",
"type": "main",
"index": 0
}
],
[
{
"node": "Start Process",
"type": "main",
"index": 0
}
]
]
},
"Assign Tasks to Teams": {
"main": [
[
{
"node": "Wait for All Teams to Finish",
"type": "main",
"index": 0
}
]
]
},
"Check Work Order Status": {
"main": [
[
{
"node": "The Dispatcher",
"type": "main",
"index": 0
}
],
[
{
"node": "The Project Dashboard (Code)",
"type": "main",
"index": 0
}
]
]
},
"The Project Dashboard (Code)": {
"main": [
[
{
"node": "Is Project Complete?",
"type": "main",
"index": 0
}
]
]
},
"Wait for All Teams to Finish": {
"main": [
[
{
"node": "Project Complete!",
"type": "main",
"index": 0
}
]
]
}
}
}