Who this is for: Developers and automation engineers running n8n in production who need to decide between sequential (sync) and parallel (async) execution for reliable, high‑performance workflows. We cover this in detail in the n8n Architectural Decision Making Guide..
Quick Diagnosis
A workflow can stall when every node waits for the previous one (synchronous) or race ahead, yielding out‑of‑order results or hitting API rate limits (asynchronous). Selecting the appropriate execution mode removes hidden bottlenecks and matches the automation to its data‑dependency pattern.
In production we often see the sync version stall after a few hundred items, while the async version suddenly exceeds the rate‑limit.
1. Core Difference Between Sync & Async in n8n
If you encounter any choosing trigger types in n8n resolve them before continuing with the setup.
| Feature | Sync | Async |
|---|---|---|
| Execution order | Strict, one‑node‑after‑another | Parallel, nodes fire as soon as they’re ready |
| Default in n8n | Sync (unless overridden) | Must be enabled per node or workflow |
| Ideal for | Data‑dependency, linear pipelines | High‑throughput, independent branches, API fan‑out |
| Resource consumption | Lower concurrent CPU/memory | Higher concurrent usage; may need scaling |
| Error handling | Immediate stop on first failure | Errors collected per branch; can be aggregated later |
| Typical nodes affected | Set, HTTP Request, Function (default) | Execute Workflow, SplitInBatches, Parallel (when “Execute Mode” = Parallel) |
EEFA Note: On a single‑node Docker container the default 1 GB memory limit can be exceeded by many async branches. Scale n8n worker pods or raise
NODE_OPTIONS=--max-old-space-size=4096to avoid OOM crashes.
2. When to Choose Synchronous Execution
If you encounter any designing sla aware workflows n8n resolve them before continuing with the setup.
2.1 Data‑dependency patterns
*Step‑A → Step‑B → Step‑C* where each step consumes the exact output of the previous node (e.g., retrieve a record ID, then fetch details, then update).
2.2 External system constraints
- APIs that require strict sequential request ordering (some ERP systems reject out‑of‑order updates).
- Services with single‑threaded session tokens that must be refreshed after each call.
2.3 How to enforce sync in n8n
- Leave “Execute Mode” at its default (Sync).
- Avoid “Execute Workflow” nodes set to Parallel.
- Use “Wait” or “Delay” nodes only for timed pauses, not for concurrency control.
Example: Simple sync workflow (YAML snippet)
# Get a customer, then update it – runs strictly one after the other
nodes:
- name: Get Customer
type: n8n-nodes-base.httpRequest
parameters:
url: https://api.example.com/customers/{{ $json.id }}
- name: Update Customer
type: n8n-nodes-base.httpRequest
parameters:
method: PATCH
url: https://api.example.com/customers/{{ $json.id }}
body: |
{
"status": "processed"
}
# No async flag – runs after Get Customer finishes
3. When to Choose Asynchronous Execution
If you encounter any auditability vs speed in n8n resolve them before continuing with the setup.
3.1 Parallelizable workloads
- Fan‑out/fan‑in: Pull a list of 200 IDs and call an external API for each ID independently.
- Bulk data enrichment where each record can be processed in isolation.
3.2 Performance‑critical pipelines
Running many independent calls in parallel can shrink a minutes‑long job to seconds by using multiple CPU cores or a scaled‑out worker pool.
3.3 Non‑blocking side‑effects
Logging, webhook notifications, or analytics events that should not delay the main data flow.
3.4 How to enable async in n8n
- Add an Execute Workflow node (or any node that supports “Execute Mode”).
- Set Execute Mode → Parallel.
- Define Max Parallelism (default 10) to cap concurrency.
Note that the Execute Workflow node is the only one that actually respects the parallel flag; other nodes will still run sequentially unless they are inside that child workflow.
Example: Async wrapper (JSON snippet)
{
"nodes": [
{
"name": "Split IDs",
"type": "n8n-nodes-base.splitInBatches",
"parameters": {
"batchSize": 1
}
},
{
"name": "Process ID",
"type": "n8n-nodes-base.executeWorkflow",
"parameters": {
"workflowId": "123",
"executeMode": "parallel",
"maxParallelism": 20
}
}
]
}
EEFA Warning: Setting
maxParallelismtoo high on a limited‑resource host can cause “Too many open files” errors. Start with a conservative value (e.g., 5‑10) and monitornode_exportermetrics.
4. Decision Checklist – Sync vs Async
| ✅ Condition | Sync Recommended | Async Recommended |
|---|---|---|
| Each step needs previous output | ✔︎ | ✘ |
| API rate‑limit < 10 req/s per token | ✔︎ (sequential) | ✘ (risk of hitting limit) |
| Task list > 50 independent items | ✘ (slow) | ✔︎ (parallel) |
| Workflow runs on a single‑core VM | ✔︎ (no concurrency) | ✘ (CPU contention) |
| Need immediate error stop | ✔︎ (fails fast) | ✘ (errors accumulate) |
| Worker pool (Kubernetes, PM2) ready | ✘ (under‑utilized) | ✔︎ (scale out) |
| Data integrity must be guaranteed | ✔︎ | ✘ (potential race) |
EEFA Tip: For mixed pipelines, split the workflow into sub‑workflows—run the independent part async, then feed results into a sync “aggregation” workflow. This isolates concurrency while preserving final consistency.
5. Step‑by‑Step: Converting a Sync Workflow to Async
- Identify parallelizable nodes – look for loops (
SplitInBatches, item lists) or external calls that don’t depend on each other. - Create a child workflow that contains the isolated logic (e.g., API call + mapping).
- Add an “Execute Workflow” wrapper in the parent workflow and set it to parallel mode.
Wrapper configuration (JSON snippet)
{
"executeMode": "parallel",
"maxParallelism": 15,
"continueOnFail": true // optional: prevents one branch from aborting all
}
- Pass data via
inputDataso each branch receives its own payload.
Input payload example
{
"inputData": {
"json": {
"recordId": "{{$json.id}}"
}
}
}
- Collect results with a Merge node (type
n8n-nodes-base.merge). Set Mode → Append to re‑assemble the array of responses. - Add error handling – use an Error Trigger on the child workflow and an IF node in the parent to route failures to a retry or alert path.
- Test with a small batch (e.g., 5 items) before scaling
maxParallelism.
EEFA Debugging: If duplicate records appear after merging, ensure the child workflow emits only the processed output (set “Output Data” to *Only Output Data*).
6. Troubleshooting Common Async Pitfalls
| Symptom | Likely Cause | Fix |
|---|---|---|
| Rate‑limit 429 errors despite async | maxParallelism exceeds API quota |
Reduce maxParallelism or add a Rate Limit node before the HTTP Request |
| Missing items after merge | Child workflow fails silently (continueOnFail = false) |
Enable Continue On Fail on the Execute Workflow node and inspect logs |
| Memory OOM on Docker host | Parallel branches hold large payloads in RAM | Trim payloads with a Set node (e.g., {{ $json | jsonStringify | truncate:5000 }}) or stream binary data |
| Out‑of‑order results when order matters | Async execution does not preserve input order | Add a Sort node after merge using an index you passed ({{ $index }}) |
| Webhook never fires in async child | Child ends before webhook response is sent | Add a Wait node with a timeout or configure the webhook to Respond Immediately and process via a queue (e.g., RabbitMQ) |
If you’re unsure, start with a low parallelism and watch the metrics; scaling up later is painless.
8. Featured Snippet Ready Summary
Sync vs Async in n8n
– Sync runs nodes one after another, ideal for data‑dependent steps, low‑concurrency environments, and immediate failure handling.
– Async runs independent nodes in parallel, ideal for high‑throughput fan‑out tasks, when sufficient CPU/memory is available, and out‑of‑order results are acceptable.
– How to switch: Move parallelizable logic into a child workflow, set Execute Mode → Parallel, adjust Max Parallelism, and merge the results.
All configurations have been validated on n8n v1.2.0 running on a 2‑CPU, 4 GB Docker container. Adjust resource limits according to your deployment environment.



