n8n sub-workflows with the Execute Sub-workflow node
Updated 2026-10-21 · 5 min read
Sub-workflows let one n8n workflow call another, pass it data and get a result back. They are n8n's answer to shared functions: one "send invoice" or "enrich lead" workflow used by ten others, instead of ten copies of the same nodes. This guide covers both nodes involved, how data passes, the settings that matter, and how to restructure Pipedream projects that relied on workflows calling workflows.
The two nodes
| Node | Where | Role |
|---|---|---|
| Execute Sub-workflow | Parent (calling) workflow | Calls the sub-workflow and receives its output |
| Execute Sub-workflow Trigger ("When Executed by Another Workflow") | First node of the sub-workflow | Receives the input and starts it |
Older templates and workflow JSON call them Execute Workflow and Execute Workflow Trigger. Same nodes.
Build the sub-workflow
- Create a new workflow and add Execute Sub-workflow Trigger.
- Choose the Input data mode (trigger docs):
| Input data mode | What the caller sees |
|---|---|
| Define using fields below | Named inputs with types, shown as a form in the calling node |
| Define using JSON example | Inputs derived from an example object |
| Accept all data | No declared inputs; the sub-workflow must handle whatever arrives |
- Add the nodes that do the work.
- Save. The docs note that a sub-workflow with errors can't be triggered by the parent.
Declared inputs are worth the extra minute. The calling node shows them as fields to fill, with an option to Attempt to convert types, and anyone reading the sub-workflow knows what it expects.
Who can call it
In the sub-workflow's settings, This workflow can be called by restricts which workflows may call it (workflow settings). Restrict it for anything that writes data or sends messages.
Call it from the parent
Add Execute Sub-workflow and set Source:
| Source | Loads the workflow from |
|---|---|
| Database | Your n8n instance, From list or by Workflow ID |
| Local File | A JSON file path on the n8n host |
| Parameter | Workflow JSON pasted into the node |
| URL | A URL that returns workflow JSON |
Database is the normal choice. The workflow ID is the string after /workflow/ in its URL.
Mode:
- Run once with all items: all input items go into one sub-workflow execution.
- Run once for each item: one sub-workflow execution per item.
Option: Wait for Sub-Workflow Completion. On: the parent waits and receives the result. Off: fire-and-forget, the parent continues immediately.
You can jump between executions: the Execute Sub-workflow node has a View sub-execution link, and the sub-execution links back to the parent.
How data comes back
- The Execute Sub-workflow node sends its input to the sub-workflow's trigger.
- The last node of the sub-workflow returns its output to the Execute Sub-workflow node, which outputs it as its own items.
So design the end of each sub-workflow on purpose. If the last node is a Slack message, the parent receives Slack's API response. Add an Edit Fields (Set) node at the end that returns exactly what callers need, such as { ok: true, invoiceId }.
Patterns
Shared utility
"Normalize a contact" called from every lead source: input email, name, source; output a cleaned record. Fix a bug once, every caller gets the fix.
Splitting a big workflow
Large workflows are hard to read and, on self-hosted n8n, can run into memory issues; the docs list memory as a reason to split. Since n8n 1.97.0 you can select nodes and use Convert to sub-workflow from the canvas menu (conversion docs). Rules: no trigger nodes in the selection, a single entry node and a single exit node, and everything between them selected. Check expressions using first(), last() and all() afterwards; n8n tries to rewrite them but doesn't guarantee it.
Per-item isolation
Run once for each item, with On Error: Continue (using error output) on the Execute Sub-workflow node: a bad record fails its own sub-execution and goes to the error output, instead of stopping the parent (without that setting, a failed sub-execution fails the parent node). Pair this with an error workflow for alerts.
Background jobs
Wait for Sub-Workflow Completion off: a webhook workflow accepts the request, starts the heavy sub-workflow and responds right away.
Billing and limits
n8n's docs state that sub-workflow executions don't count towards your plan's monthly execution or active workflow limits (sub-workflows). On n8n Cloud, where plans are priced by executions, splitting a workflow into a parent and helpers doesn't multiply the bill. That makes a design with many small sub-workflows cheaper than it looks.
Sub-workflow vs alternatives
| Need | Use |
|---|---|
| Reuse logic inside n8n | Execute Sub-workflow |
| Call a workflow from outside n8n | Webhook node on the target workflow |
| Run something on failure | Error workflow (Error Trigger) |
| Let an AI agent call a workflow | Call n8n Workflow Tool node (it also starts the Execute Sub-workflow Trigger) |
Calling your own workflows over HTTP works too, but you lose typed inputs, the execution links and the billing exemption, and you have to secure the endpoint.
From Pipedream: workflows calling workflows
Pipedream had no first-class sub-workflow node. Teams used three patterns:
| Pipedream pattern | n8n equivalent |
|---|---|
| One workflow POSTs to another workflow's HTTP trigger URL | Execute Sub-workflow (keep the Webhook trigger if outside systems still call it) |
$.flow.trigger() in code (alpha, per the Node.js docs) |
Execute Sub-workflow |
| Copy-pasted steps across workflows | One sub-workflow, called from each |
During migration the URLs between workflows change: every *.m.pipedream.net URL one workflow calls becomes either an Execute Sub-workflow node or a new n8n webhook URL. List them before you start. Search the exported JSON files for m.pipedream.net to find them; the converter report then shows, per workflow, which triggers and steps need manual work. $.flow.trigger() calls in code aren't converted or flagged automatically: search for them and rebuild them as Execute Sub-workflow nodes. The code step checker shows what else a step uses. The report and 1 workflow are free. Full export: $3 per workflow, $19 minimum — coming soon. Full process: migrate Pipedream to n8n.
Not affiliated with Pipedream or n8n.
FAQ
- How do I call another workflow in n8n?
- Start the called workflow with the Execute Sub-workflow Trigger (also listed as When Executed by Another Workflow). In the calling workflow add an Execute Sub-workflow node and select the workflow from the list or by ID.
- How does a sub-workflow return data in n8n?
- The output of the sub-workflow's last node is returned to the Execute Sub-workflow node in the parent workflow, which outputs it as its own items.
- Do sub-workflow executions count against my n8n plan?
- No. n8n's docs say sub-workflow executions don't count towards the plan's monthly execution or active workflow limits.
- Can the parent workflow continue without waiting for the sub-workflow?
- Yes. Turn off the Wait for Sub-Workflow Completion option on the Execute Sub-workflow node.
- Is Execute Workflow the same as Execute Sub-workflow?
- Yes. The node was renamed; older docs, templates and workflow JSON still use Execute Workflow and Execute Workflow Trigger.
Related
Sources
- https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflow
- https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflowtrigger
- https://docs.n8n.io/build/flow-logic/break-workflows-into-smaller-parts
- https://docs.n8n.io/build/flow-logic/convert-to-sub-workflows
- https://docs.n8n.io/build/manage-workflows/configure-workflow-settings
- https://pipedream.com/docs/workflows/building-workflows/code/nodejs