n8n-loops-official
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesen8n Loops
n8n 循环
Three meanings of "loop" map to three mechanisms:
- "Run this node for every item." Default. Most nodes loop automatically, so do nothing.
- "Run this node once with all items, not once per item." The setting (single boolean).
executeOnce - "Process items in explicit batches with control flow between iterations." The node (formerly
Loop Over Items).Split In Batches
For paginated APIs, the HTTP Request node has built-in pagination. Almost always preferable to a hand-built page-counting loop.
「循环」的三种含义对应三种机制:
- 「为每个条目运行此节点。」 默认行为。大多数节点会自动循环,无需额外操作。
- 「一次运行此节点,处理所有条目,而非每个条目运行一次。」 使用 设置(单个布尔值)。
executeOnce - 「通过迭代间的控制流显式批量处理条目。」 使用 节点(原
Loop Over Items)。Split In Batches
对于分页API,HTTP Request节点内置分页功能。几乎总是比手动构建的页数计数循环更优。
The model: items are an array
模型:条目为数组
Data flows between nodes as an array of items, each . 50 items = 50-entry array.
{ json: {...}, binary?: {...} }Default: a node runs once per item. An HTTP Request with 50 input items fires 50 requests and outputs 50 result items. This is the implicit loop most workflows rely on.
The input array is the loop. Control iteration by controlling the array.
节点间的数据以条目数组形式流转,每个条目格式为 。50个条目即对应50元素的数组。
{ json: {...}, binary?: {...} }默认行为:节点每个条目运行一次。传入50个输入条目的HTTP Request会发起50次请求,并输出50个结果条目。这是大多数工作流依赖的隐式循环。
输入数组就是循环本身。 通过控制数组来控制迭代。
Non-negotiable
必须遵循的规则
executeOnce: true$input.all()$('Node').all().map().filter().reduce()Counter-case: combined with another node's (a per-item lookup, e.g., ) is real per-item work and should keep off. See the skill's executeOnce section for the full distinction.
.all().item$('Get Tags').all().filter(tag => $('Search Posts').item.json.tag_ids.includes(tag.json.id))executeOncen8n-expressions-official当节点应按运行次数触发一次而非每个条目触发一次时,务必设置 。 包括任何通过 / 结合 / / 对数据集进行聚合的表达式(若不设置,聚合操作会针对N个上游条目执行N次,通常会在下游产生N个重复结果)。还包括单条通知、聚合写入、汇总消息等场景。
executeOnce: true$input.all()$('Node').all().map().filter().reduce()反例: 结合另一个节点的 (按条目查询,例如 )属于真正的按条目处理工作,应保持 关闭。如需完整区分,请查看 技能的executeOnce章节。
.all().item$('Get Tags').all().filter(tag => $('Search Posts').item.json.tag_ids.includes(tag.json.id))executeOncen8n-expressions-officialStrong defaults
推荐默认做法
- Don't build a loop when default iteration suffices. Most nodes (HTTP Request, native service nodes, Set, IF/Switch) run once per input item automatically: N items in, N runs. To make N HTTP calls or create N records, just connect the source to the node. Don't reach for unless you need per-iteration control. (Note:
Loop Over Itemsis the exception. It defaults to a single all-items batch. SeeExecute Workflowforn8n-subworkflows-official.)mode: 'each' - For paginated APIs, use HTTP Request's built-in pagination. Don't reinvent with + manual
Loop Over Itemsunless the API is genuinely odd. See$pageCount.references/HTTP_PAGINATION.md - is for explicit batching or per-iteration control (rate limiting, per-batch error recovery, stateful chunks, polling). See
Loop Over Items.references/LOOP_OVER_ITEMS.md - Per-item iteration is sequential, not parallel. Each item completes before the next starts, even on parallel looking branches. For a real concurrency pattern, see .
n8n-subworkflows-official
- 当默认迭代足够时,不要手动构建循环。 大多数节点(HTTP Request、原生服务节点、Set、IF/Switch)会自动按每个输入条目运行一次:输入N个条目,运行N次。要发起N次HTTP调用或创建N条记录,只需将源节点连接到目标节点即可。除非需要迭代间控制,否则不要使用 。(注意:
Loop Over Items是例外,它默认以单批次处理所有条目。如需按条目执行,请查看Execute Workflow的n8n-subworkflows-official设置。)mode: 'each' - 对于分页API,使用HTTP Request的内置分页功能。 除非API行为特殊,否则不要用 + 手动
Loop Over Items重新实现。详情请查看$pageCount。references/HTTP_PAGINATION.md - 用于显式批量处理或迭代间控制(限频、每批次错误恢复、有状态分块、轮询)。详情请查看
Loop Over Items。references/LOOP_OVER_ITEMS.md - 按条目迭代是串行的,而非并行。 即使在看似并行的分支中,每个条目完成后下一个才会开始。如需真正的并发模式,请查看 。
n8n-subworkflows-official
Decision tree: which mechanism do I need?
决策树:我需要哪种机制?
Need to do something for each item?
├── Default per-item iteration is enough
│ └── Just connect the node. Done.
│
├── The node should run once total, not once per item?
│ └── Set executeOnce: true on the node
│
├── Paginated API (multiple HTTP calls to fetch all pages)?
│ └── Use HTTP Request's Pagination option (see references/HTTP_PAGINATION.md)
│
├── Need explicit batching (rate limit, chunk size, per-batch error handling)?
│ └── Use Loop Over Items node (see references/LOOP_OVER_ITEMS.md)
│
└── Need to recurse / repeat with state until a condition is met?
└── Loop Over Items with Reset, OR a sub-workflow that calls itself.
Both are advanced patterns; see references/LOOP_OVER_ITEMS.md.需要为每个条目执行操作?
├── 默认按条目迭代足够
│ └── 直接连接节点即可。完成。
│
├── 节点应总共运行一次,而非每个条目运行一次?
│ └── 在节点上设置 executeOnce: true
│
├── 分页API(需多次HTTP调用获取所有页面)?
│ └── 使用HTTP Request的分页选项(查看 references/HTTP_PAGINATION.md)
│
├── 需要显式批量处理(限频、分块大小、每批次错误处理)?
│ └── 使用Loop Over Items节点(查看 references/LOOP_OVER_ITEMS.md)
│
└── 需要带状态递归/重复直到满足条件?
└── 使用带Reset的Loop Over Items,或调用自身的子工作流。
两者均为高级模式;详情请查看 references/LOOP_OVER_ITEMS.md。executeOnce
: the single-fire setting
executeOnceexecuteOnce
:单次触发设置
executeOnceEvery node's Settings tab has an Execute Once toggle. When on, the node runs once using only the first input item. In SDK code, set as shown; on an existing workflow, apply it via (n8n 2.24.0+).
executeOnce: trueupdate_workflowsetNodeSettingsts
{
name: 'Aggregate Slack',
type: 'n8n-nodes-base.slack',
parameters: { /* ... */ },
executeOnce: true,
}When to use it:
- Notifications and aggregate writes. A "summary message" shouldn't fire 100 times because 100 items came in.
- Counters, totals, reports. Anything computing etc. should run once.
$input.all().length - Expressions aggregating across the full array via /
$input.all(). Otherwise the aggregate runs per upstream item. (Per-item lookups using$('Node').all()filtered by another node's.all()are the counter-case, see.item.)n8n-expressions-official
When NOT to use it:
- Per-item operations. One notification per item is the default and usually correct.
- HTTP requests fanning out per item. You want one call per item.
Most common mistake: forgetting on an aggregate node, then seeing the same message fire 50 times after a fan-out.
executeOnce每个节点的设置标签页都有一个Execute Once开关。开启后,节点仅使用第一个输入条目运行一次。在SDK代码中,按示例设置 ;对于现有工作流,可通过 的 进行设置(n8n 2.24.0+版本支持)。
executeOnce: trueupdate_workflowsetNodeSettingsts
{
name: 'Aggregate Slack',
type: 'n8n-nodes-base.slack',
parameters: { /* ... */ },
executeOnce: true,
}适用场景:
- 通知和聚合写入。 「汇总消息」不应因传入100个条目而触发100次。
- 计数器、总计、报表。 任何计算 等操作应仅运行一次。
$input.all().length - 通过 /
$input.all()对整个数组进行聚合的表达式。 否则聚合操作会针对每个上游条目运行。(通过$('Node').all()结合另一个节点的.all()进行按条目查询属于反例,详情请查看.item。)n8n-expressions-official
不适用场景:
- 按条目操作。 每个条目对应一条通知是默认行为,通常是正确的。
- 按条目扇出的HTTP请求。 你需要每个条目对应一次调用。
最常见错误:在聚合节点上忘记设置 ,导致扇出后相同消息触发50次。
executeOnceWhen the implicit loop bites you
隐式循环的陷阱
Default per-item iteration is great until it isn't. Common surprises:
默认按条目迭代通常很好,但也会有意外情况:
A "single" config node fires per item
「单个」配置节点按条目触发
A node after a fan-out runs once per item, producing N copies of the same constants. Usually fine, but expensive expressions (long , Luxon parse) run N times. Move the Set above the fan-out, or set .
SetJSON.stringifyexecuteOnce: true扇出后的 节点会按每个条目运行一次,生成N个相同常量的副本。通常没问题,但耗时的表达式(长 、Luxon解析)会运行N次。可将Set节点移到扇出之前,或设置 。
SetJSON.stringifyexecuteOnce: trueAn aggregate Code node runs N times
聚合Code节点运行N次
A Code node reading to compute a sum runs once per upstream item without , producing N identical items. Set .
$input.all()executeOnce: trueexecuteOnce: true读取 计算总和的Code节点,若未设置 ,会针对每个上游条目运行一次,生成N个相同的条目。需设置 。
$input.all()executeOnce: trueexecuteOnce: trueA respond-to-webhook fires twice
响应Webhook触发两次
Most painful version. Respond-to-Webhook fires per input item, and two branches converging without a merge fire it twice: first response wins, the rest log errors. Merge first, or ensure only one branch reaches the responder. See .
n8n-node-configuration-officialreferences/MERGE_NODE.md最棘手的情况。Respond-to-Webhook按输入条目触发,若两个分支未合并就到达该节点,会触发两次:第一次响应生效,其余响应会记录错误。需先合并分支,或确保只有一个分支到达响应节点。详情请查看 的 。
n8n-node-configuration-officialreferences/MERGE_NODE.mdAn LLM call fires N times when you wanted one summary
LLM调用触发N次,而你只需要一次汇总
Same shape as the aggregate Code node. An LLM node with in its prompt makes N identical calls, costs N tokens, returns N identical answers without .
$input.all()executeOnce: true与聚合Code节点情况相同。提示中包含 的LLM节点,若未设置 ,会发起N次相同调用,消耗N倍tokens,返回N个相同结果。
$input.all()executeOnce: trueWhen to reach for Loop Over Items
Loop Over Items何时使用 Loop Over Items
Loop Over ItemsDefault iteration handles most cases. Use for:
Loop Over Items- Rate limiting. "Process 10 at a time, 1s wait between batches."
- Batched API calls with array bodies. "Send 50-item chunks to /bulk."
- Per-batch error handling. "If a batch fails, log and continue."
- Stateful iteration. "Each iteration depends on the previous output."
- Polling a long-running job. "Start, check status every 30s until done or capped." Uses plus a
reset: trueceiling.$runIndex - Per-item multi-branch with aggregation. "For each input, run transforms in parallel, merge, then aggregate." The done output (index 0) carries the result.
For wiring details, the output-index gotcha (output 0 = done, output 1 = loop), and worked examples, see .
references/LOOP_OVER_ITEMS.md默认迭代可处理大多数场景。在以下情况使用 :
Loop Over Items- 限频。 「每次处理10个条目,批次间隔1秒。」
- 带数组请求体的批量API调用。 「向/bulk接口发送50条目的分块。」
- 每批次错误处理。 「若批次失败,记录日志并继续。」
- 有状态迭代。 「每次迭代依赖前一次输出。」
- 轮询长时间运行的任务。 「启动后每30秒检查状态,直到完成或达到上限。」需使用 结合
reset: true上限。$runIndex - 按条目多分支聚合。 「对于每个输入,并行运行转换,合并后再聚合。」完成输出(索引0)携带结果。
关于接线细节、输出索引陷阱(输出0 = 完成,输出1 = 循环)及示例,请查看 。
references/LOOP_OVER_ITEMS.mdWhen NOT to reach for Loop Over Items
Loop Over Items何时不应使用 Loop Over Items
Loop Over ItemsThe most common rationalization: "I need to wait for all items to finish before the next step, so I'll add Loop Over Items and use the output." You don't need Loop Over Items for that. Default per-item iteration already waits: each item flows through the full downstream chain before the next item starts, and the post-loop node never fires "early."
doneThe cure for that mistake is almost always: delete the Loop Over Items node, change nothing else, ship. That is Scenario 1 below, and it covers the majority of cases.
The four scenarios are independent. Read them as separate decisions, not as alternatives that all "replace" Loop Over Items. Most builds hit Scenario 1 and are done. Scenarios 2 and 3 only enter the picture when their specific goal applies. Scenario 4 is the narrow case where Loop Over Items actually earns its place.
最常见的错误理由:「我需要等待所有条目完成后再执行下一步,所以添加Loop Over Items并使用输出。」你不需要Loop Over Items来实现这个功能。 默认按条目迭代已经会等待:每个条目完成整个下游流程后,下一个条目才会开始,循环后的节点永远不会「提前」触发。
done解决这个错误的方法几乎总是:删除Loop Over Items节点,其余保持不变,即可上线。 这是下方的场景1,覆盖了大多数情况。
四个场景相互独立,应视为独立决策,而非替代Loop Over Items的方案。大多数构建仅涉及场景1即可完成。场景2和3仅在特定目标适用时才需要考虑。场景4是Loop Over Items真正适用的窄范围场景。
Scenario 1: default per-item iteration (the default, most common)
场景1:默认按条目迭代(默认行为,最常见)
Source emits N items, per-item processor runs N times, downstream chain follows. No Loop Over Items, no , no Aggregate. Just connect the nodes.
executeOnce[Source: 20 items]
→ [Per-item processor] # default iter, runs 20 times
→ [Next step] # runs after each item, in orderIf a was added here "to wait for all items" or "to make the next node run for each item," delete the Loop Over Items node and wire source straight to processor. Do not replace it with anything. Default iteration already does the job. The exception is (sub-workflow): it defaults to a single all-items batch, so per-item invocation needs on that node, not a Loop. See .
Loop Over Items + doneExecute Workflowmode: 'each'n8n-subworkflows-official源节点输出N个条目,按条目处理器运行N次,下游流程跟进。无需Loop Over Items、无需、无需聚合。 只需连接节点即可。
executeOnce[源节点:20个条目]
→ [按条目处理器] # 默认迭代,运行20次
→ [下一步] # 按顺序在每个条目完成后运行如果此处添加是为了「等待所有条目完成」或「让下一个节点按每个条目运行」,请删除Loop Over Items节点,直接将源节点连接到处理器。无需替换为任何其他节点。 默认迭代已经实现该功能。例外情况是(子工作流):它默认以单批次处理所有条目,因此按条目调用需要在该节点上设置,而非使用循环。详情请查看。
Loop Over Items + doneExecute Workflowmode: 'each'n8n-subworkflows-officialScenario 2: a downstream node should fire once total (executeOnce: true
)
executeOnce: true场景2:下游节点应总共触发一次(executeOnce: true
)
executeOnce: trueIndependent of Scenario 1. Triggered only when there is a SPECIFIC downstream node whose job is once-per-run, not once-per-item: one digest email after 20 papers process, one summary write after the loop, one final Slack notification.
Set on that node. The node receives all upstream items but runs once. This is a per-node setting, not a Loop replacement: the per-item processor in Scenario 1 still runs N times, and only this one downstream node collapses.
executeOnce: true独立于场景1。仅当存在特定的下游节点需要按运行次数触发一次而非每个条目触发一次时才适用:处理20篇论文后发送一封摘要邮件,循环后进行一次汇总写入,发送一条最终Slack通知。
在该节点上设置。节点会接收所有上游条目,但仅运行一次。这是节点级设置,而非循环替代方案:场景1中的按条目处理器仍会运行N次,只有这个下游节点会合并为单次运行。
executeOnce: trueScenario 3: a node needs the items as a single array (Aggregate)
场景3:节点需要条目作为单个数组(聚合)
Independent of Scenario 1. Triggered only when a downstream node's input contract is a list, not per-item invocations (e.g., a node taking a JSON array body, an LLM prompt that needs the whole list).
Use the Aggregate node to collapse the per-item stream into one item containing the array. Again, not a Loop replacement.
独立于场景1。仅当下游节点的输入要求为列表而非按条目调用时才适用(例如,接收JSON数组请求体的节点,需要整个列表作为提示的LLM节点)。
使用Aggregate节点将按条目流合并为包含数组的单个条目。同样,这不是循环替代方案。
Scenario 4: genuine batching (the only time Loop Over Items earns its place)
场景4:真正的批量处理(Loop Over Items唯一适用场景)
Rate limiting (process N at a time with a Wait between batches), chunked bulk API calls (POST 50-item arrays to ), per-batch error handling, polling a long-running job with and a ceiling, stateful iteration where each batch depends on the previous output.
/bulkreset: true$runIndex"Wait for items to finish" does not qualify. Default iteration already does that.
限频(每次处理N个条目,批次间等待)、分块批量API调用(向接口POST50条目的数组)、每批次错误处理、使用和上限轮询长时间运行的任务、每次批次依赖前一次输出的有状态迭代。
/bulkreset: true$runIndex「等待条目完成」不属于此场景。默认迭代已经实现该功能。
Quick disambiguation
快速区分
If your only reason for the Loop is "wait for items / run for each item," you are in Scenario 1. Delete the Loop. Do not add or Aggregate as a substitute. They solve different problems and are only added when their own scenario applies.
executeOnce如果你使用循环的唯一理由是「等待条目完成/按每个条目运行」,那么你属于场景1。删除循环即可。无需添加或Aggregate作为替代,它们解决的是不同问题,仅在对应场景适用时才添加。
executeOnceWhen to reach for HTTP pagination
何时使用HTTP分页
Three common page shapes:
- Next-URL in response. Each response includes a link.
next - Page number/cursor parameter. Bump or
?page=Neach call.?cursor=... - Stop on empty page or specific status.
HTTP Request handles all natively via its Pagination option: set the mode, give a next-page expression, and the node loops internally, returning a single output array of all pages' items.
Don't reinvent with + manual unless the API does something the built-in modes can't express.
Loop Over Items$pageCountSee .
references/HTTP_PAGINATION.md三种常见的页面形式:
- 响应中包含Next-URL。 每个响应包含一个链接。
next - 页码/游标参数。 每次调用递增或
?page=N。?cursor=... - 空页面或特定状态时停止。
HTTP Request节点通过其Pagination选项原生支持所有形式:设置模式,提供下一页表达式,节点会在内部循环,返回包含所有页面条目的单个输出数组。
除非API行为无法通过内置模式表达,否则不要用 + 手动重新实现。
Loop Over Items$pageCount详情请查看。
references/HTTP_PAGINATION.mdSub-workflow recursion
子工作流递归
For genuinely recursive work (tree walking, retry-with-backoff, "process this and its children"), a self-calling sub-workflow is cleaner than with . Input parameters carry recursion state.
Loop Over ItemsResetSub-workflow: Walk Tree
inputs: { node_id, depth }
body: process node, look up children, for each child call self with depth+1Watch recursion depth. n8n has nested-execution limits. For deep recursion, a queue + flat loop beats true recursion.
对于真正的递归工作(树遍历、退避重试、「处理此条目及其子条目」),自调用子工作流比带的更简洁。输入参数携带递归状态。
ResetLoop Over Items子工作流:Walk Tree
inputs: { node_id, depth }
body: 处理节点,查询子节点,为每个子节点调用自身并传入depth+1注意递归深度。n8n有嵌套执行限制。对于深度递归,队列+扁平循环优于真正的递归。
Reference files
参考文件
| File | Read when |
|---|---|
| Configuring the Loop Over Items node, batching, rate limiting, stateful iteration |
| Calling a paginated API, configuring HTTP Request pagination modes |
| 文件 | 阅读场景 |
|---|---|
| 配置Loop Over Items节点、批量处理、限频、有状态迭代 |
| 调用分页API、配置HTTP Request分页模式 |
Anti-patterns
反模式
| Anti-pattern | What goes wrong | Fix |
|---|---|---|
Adding | Workflow harder to read for no benefit, and loop output vs done output gets miswired | Just connect the node directly and let default iteration handle it |
Aggregate Code node without | Same aggregate computed N times, output has N identical items | Set |
Manual pagination loop with | Reinvents what HTTP Request does natively, with brittle stop conditions | Use HTTP Request's |
| Sending one Slack message per item when you wanted a summary | Slack channel floods, rate limits hit, embarrassment | |
Two branches both reach | Responds twice, downstream callers see errors | Merge before the responder, or ensure only one branch reaches it |
| Infinite loop, n8n eats memory until the execution is killed | Always have a clear termination condition. Prefer HTTP pagination for paged APIs |
Nesting one | Broken at runtime, validation passes | Move the inner loop into a sub-workflow called per outer iteration. See |
| 反模式 | 问题 | 修复方案 |
|---|---|---|
在默认迭代已实现循环时添加 | 工作流可读性降低且无收益,容易误接循环输出与完成输出 | 直接连接节点,让默认迭代处理即可 |
聚合Code节点未设置 | 相同聚合操作执行N次,输出包含N个相同条目 | 设置 |
使用 | 重复HTTP Request原生功能,停止条件脆弱 | 使用HTTP Request的 |
| 每个条目发送一条Slack消息,而你需要的是汇总 | Slack频道被刷屏,触发限频,造成困扰 | 在Slack节点上设置 |
两个分支均到达 | 响应两次,下游调用方看到错误 | 在响应节点前合并分支,或确保只有一个分支到达响应节点 |
带 | 无限循环,n8n消耗内存直到执行被终止 | 始终设置明确的终止条件。分页API优先使用HTTP分页 |
在同一工作流中嵌套 | 运行时出错,但验证通过 | 将内部循环移到子工作流中,在外层迭代时调用。详情请查看 |