n8n-loops-official

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

n8n Loops

n8n 循环

Three meanings of "loop" map to three mechanisms:
  1. "Run this node for every item." Default. Most nodes loop automatically, so do nothing.
  2. "Run this node once with all items, not once per item." The
    executeOnce
    setting (single boolean).
  3. "Process items in explicit batches with control flow between iterations." The
    Loop Over Items
    node (formerly
    Split In Batches
    ).
For paginated APIs, the HTTP Request node has built-in pagination. Almost always preferable to a hand-built page-counting loop.
「循环」的三种含义对应三种机制:
  1. 「为每个条目运行此节点。」 默认行为。大多数节点会自动循环,无需额外操作。
  2. 「一次运行此节点,处理所有条目,而非每个条目运行一次。」 使用
    executeOnce
    设置(单个布尔值)。
  3. 「通过迭代间的控制流显式批量处理条目。」 使用
    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
{ json: {...}, binary?: {...} }
. 50 items = 50-entry array.
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.
节点间的数据以条目数组形式流转,每个条目格式为
{ json: {...}, binary?: {...} }
。50个条目即对应50元素的数组。
默认行为:节点每个条目运行一次。传入50个输入条目的HTTP Request会发起50次请求,并输出50个结果条目。这是大多数工作流依赖的隐式循环。
输入数组就是循环本身。 通过控制数组来控制迭代。

Non-negotiable

必须遵循的规则

executeOnce: true
whenever a node should fire once-per-run, not once-per-item.
Includes any expression aggregating across the dataset via
$input.all()
/
$('Node').all()
plus
.map()
/
.filter()
/
.reduce()
(without it, the aggregate computes N times for N upstream items, often producing N duplicates downstream). Also includes single notifications, aggregate writes, summary messages.
Counter-case:
.all()
combined with another node's
.item
(a per-item lookup, e.g.,
$('Get Tags').all().filter(tag => $('Search Posts').item.json.tag_ids.includes(tag.json.id))
) is real per-item work and should keep
executeOnce
off. See the
n8n-expressions-official
skill's executeOnce section for the full distinction.
当节点应按运行次数触发一次而非每个条目触发一次时,务必设置
executeOnce: true
包括任何通过
$input.all()
/
$('Node').all()
结合
.map()
/
.filter()
/
.reduce()
对数据集进行聚合的表达式(若不设置,聚合操作会针对N个上游条目执行N次,通常会在下游产生N个重复结果)。还包括单条通知、聚合写入、汇总消息等场景。
反例:
.all()
结合另一个节点的
.item
(按条目查询,例如
$('Get Tags').all().filter(tag => $('Search Posts').item.json.tag_ids.includes(tag.json.id))
)属于真正的按条目处理工作,应保持
executeOnce
关闭。如需完整区分,请查看
n8n-expressions-official
技能的executeOnce章节。

Strong 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
    Loop Over Items
    unless you need per-iteration control. (Note:
    Execute Workflow
    is the exception. It defaults to a single all-items batch. See
    n8n-subworkflows-official
    for
    mode: 'each'
    .)
  • For paginated APIs, use HTTP Request's built-in pagination. Don't reinvent with
    Loop Over Items
    + manual
    $pageCount
    unless the API is genuinely odd. See
    references/HTTP_PAGINATION.md
    .
  • Loop Over Items
    is for explicit batching or per-iteration control
    (rate limiting, per-batch error recovery, stateful chunks, polling). See
    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

executeOnce
:单次触发设置

Every 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
executeOnce: true
as shown; on an existing workflow, apply it via
update_workflow
setNodeSettings
(n8n 2.24.0+).
ts
{
    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
    $input.all().length
    etc. should run once.
  • Expressions aggregating across the full array via
    $input.all()
    /
    $('Node').all()
    .
    Otherwise the aggregate runs per upstream item. (Per-item lookups using
    .all()
    filtered by another node's
    .item
    are the counter-case, see
    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
executeOnce
on an aggregate node, then seeing the same message fire 50 times after a fan-out.
每个节点的设置标签页都有一个Execute Once开关。开启后,节点仅使用第一个输入条目运行一次。在SDK代码中,按示例设置
executeOnce: true
;对于现有工作流,可通过
update_workflow
setNodeSettings
进行设置(n8n 2.24.0+版本支持)。
ts
{
    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请求。 你需要每个条目对应一次调用。
最常见错误:在聚合节点上忘记设置
executeOnce
,导致扇出后相同消息触发50次。

When 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
Set
node after a fan-out runs once per item, producing N copies of the same constants. Usually fine, but expensive expressions (long
JSON.stringify
, Luxon parse) run N times. Move the Set above the fan-out, or set
executeOnce: true
.
扇出后的
Set
节点会按每个条目运行一次,生成N个相同常量的副本。通常没问题,但耗时的表达式(长
JSON.stringify
、Luxon解析)会运行N次。可将Set节点移到扇出之前,或设置
executeOnce: true

An aggregate Code node runs N times

聚合Code节点运行N次

A Code node reading
$input.all()
to compute a sum runs once per upstream item without
executeOnce: true
, producing N identical items. Set
executeOnce: true
.
读取
$input.all()
计算总和的Code节点,若未设置
executeOnce: true
,会针对每个上游条目运行一次,生成N个相同的条目。需设置
executeOnce: true

A 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-official
references/MERGE_NODE.md
.
最棘手的情况。Respond-to-Webhook按输入条目触发,若两个分支未合并就到达该节点,会触发两次:第一次响应生效,其余响应会记录错误。需先合并分支,或确保只有一个分支到达响应节点。详情请查看
n8n-node-configuration-official
references/MERGE_NODE.md

An LLM call fires N times when you wanted one summary

LLM调用触发N次,而你只需要一次汇总

Same shape as the aggregate Code node. An LLM node with
$input.all()
in its prompt makes N identical calls, costs N tokens, returns N identical answers without
executeOnce: true
.
与聚合Code节点情况相同。提示中包含
$input.all()
的LLM节点,若未设置
executeOnce: true
,会发起N次相同调用,消耗N倍tokens,返回N个相同结果。

When to reach for
Loop Over Items

何时使用
Loop Over Items

Default iteration handles most cases. Use
Loop Over Items
for:
  • 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
    reset: true
    plus a
    $runIndex
    ceiling.
  • 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.md

When NOT to reach for
Loop Over Items

何时不应使用
Loop Over Items

The 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
done
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."
The 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并使用
done
输出。」你不需要Loop Over Items来实现这个功能。 默认按条目迭代已经会等待:每个条目完成整个下游流程后,下一个条目才会开始,循环后的节点永远不会「提前」触发。
解决这个错误的方法几乎总是:删除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
executeOnce
, no Aggregate.
Just connect the nodes.
[Source: 20 items]
  → [Per-item processor]   # default iter, runs 20 times
  → [Next step]            # runs after each item, in order
If a
Loop Over Items + done
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
Execute Workflow
(sub-workflow): it defaults to a single all-items batch, so per-item invocation needs
mode: 'each'
on that node, not a Loop. See
n8n-subworkflows-official
.
源节点输出N个条目,按条目处理器运行N次,下游流程跟进。无需Loop Over Items、无需
executeOnce
、无需聚合。
只需连接节点即可。
[源节点:20个条目]
  → [按条目处理器]   # 默认迭代,运行20次
  → [下一步]            # 按顺序在每个条目完成后运行
如果此处添加
Loop Over Items + done
是为了「等待所有条目完成」或「让下一个节点按每个条目运行」,请删除Loop Over Items节点,直接将源节点连接到处理器。无需替换为任何其他节点。 默认迭代已经实现该功能。例外情况是
Execute Workflow
(子工作流):它默认以单批次处理所有条目,因此按条目调用需要在该节点上设置
mode: 'each'
,而非使用循环。详情请查看
n8n-subworkflows-official

Scenario 2: a downstream node should fire once total (
executeOnce: true
)

场景2:下游节点应总共触发一次(
executeOnce: true

Independent 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
executeOnce: true
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.
独立于场景1。仅当存在特定的下游节点需要按运行次数触发一次而非每个条目触发一次时才适用:处理20篇论文后发送一封摘要邮件,循环后进行一次汇总写入,发送一条最终Slack通知。
在该节点上设置
executeOnce: true
。节点会接收所有上游条目,但仅运行一次。这是节点级设置,而非循环替代方案:场景1中的按条目处理器仍会运行N次,只有这个下游节点会合并为单次运行。

Scenario 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
/bulk
), per-batch error handling, polling a long-running job with
reset: true
and a
$runIndex
ceiling, stateful iteration where each batch depends on the previous output.
"Wait for items to finish" does not qualify. Default iteration already does that.
限频(每次处理N个条目,批次间等待)、分块批量API调用(向
/bulk
接口POST50条目的数组)、每批次错误处理、使用
reset: 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
executeOnce
or Aggregate as a substitute. They solve different problems and are only added when their own scenario applies.
如果你使用循环的唯一理由是「等待条目完成/按每个条目运行」,那么你属于场景1。删除循环即可。无需添加
executeOnce
或Aggregate作为替代,它们解决的是不同问题,仅在对应场景适用时才添加。

When to reach for HTTP pagination

何时使用HTTP分页

Three common page shapes:
  • Next-URL in response. Each response includes a
    next
    link.
  • Page number/cursor parameter. Bump
    ?page=N
    or
    ?cursor=...
    each call.
  • 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
Loop Over Items
+ manual
$pageCount
unless the API does something the built-in modes can't express.
See
references/HTTP_PAGINATION.md
.
三种常见的页面形式:
  • 响应中包含Next-URL。 每个响应包含一个
    next
    链接。
  • 页码/游标参数。 每次调用递增
    ?page=N
    ?cursor=...
  • 空页面或特定状态时停止。
HTTP Request节点通过其Pagination选项原生支持所有形式:设置模式,提供下一页表达式,节点会在内部循环,返回包含所有页面条目的单个输出数组。
除非API行为无法通过内置模式表达,否则不要用
Loop Over Items
+ 手动
$pageCount
重新实现。
详情请查看
references/HTTP_PAGINATION.md

Sub-workflow recursion

子工作流递归

For genuinely recursive work (tree walking, retry-with-backoff, "process this and its children"), a self-calling sub-workflow is cleaner than
Loop Over Items
with
Reset
. Input parameters carry recursion state.
Sub-workflow: Walk Tree
  inputs: { node_id, depth }
  body: process node, look up children, for each child call self with depth+1
Watch recursion depth. n8n has nested-execution limits. For deep recursion, a queue + flat loop beats true recursion.
对于真正的递归工作(树遍历、退避重试、「处理此条目及其子条目」),自调用子工作流比带
Reset
Loop Over Items
更简洁。输入参数携带递归状态。
子工作流:Walk Tree
  inputs: { node_id, depth }
  body: 处理节点,查询子节点,为每个子节点调用自身并传入depth+1
注意递归深度。n8n有嵌套执行限制。对于深度递归,队列+扁平循环优于真正的递归。

Reference files

参考文件

FileRead when
references/LOOP_OVER_ITEMS.md
Configuring the Loop Over Items node, batching, rate limiting, stateful iteration
references/HTTP_PAGINATION.md
Calling a paginated API, configuring HTTP Request pagination modes
文件阅读场景
references/LOOP_OVER_ITEMS.md
配置Loop Over Items节点、批量处理、限频、有状态迭代
references/HTTP_PAGINATION.md
调用分页API、配置HTTP Request分页模式

Anti-patterns

反模式

Anti-patternWhat goes wrongFix
Adding
Loop Over Items
to "make it loop" when default iteration already does
Workflow harder to read for no benefit, and loop output vs done output gets miswiredJust connect the node directly and let default iteration handle it
Aggregate Code node without
executeOnce
Same aggregate computed N times, output has N identical itemsSet
executeOnce: true
Manual pagination loop with
Loop Over Items
+
$pageCount
Reinvents what HTTP Request does natively, with brittle stop conditionsUse HTTP Request's
Pagination
option
Sending one Slack message per item when you wanted a summarySlack channel floods, rate limits hit, embarrassment
executeOnce: true
on the Slack node, build the summary upstream
Two branches both reach
Respond to Webhook
Responds twice, downstream callers see errorsMerge before the responder, or ensure only one branch reaches it
Loop Over Items
with
Reset
and no clear termination
Infinite loop, n8n eats memory until the execution is killedAlways have a clear termination condition. Prefer HTTP pagination for paged APIs
Nesting one
Loop Over Items
inside another in the same workflow
Broken at runtime, validation passesMove the inner loop into a sub-workflow called per outer iteration. See
n8n-subworkflows-official
mode: 'each'
反模式问题修复方案
在默认迭代已实现循环时添加
Loop Over Items
「实现循环」
工作流可读性降低且无收益,容易误接循环输出与完成输出直接连接节点,让默认迭代处理即可
聚合Code节点未设置
executeOnce
相同聚合操作执行N次,输出包含N个相同条目设置
executeOnce: true
使用
Loop Over Items
+
$pageCount
手动实现分页循环
重复HTTP Request原生功能,停止条件脆弱使用HTTP Request的
Pagination
选项
每个条目发送一条Slack消息,而你需要的是汇总Slack频道被刷屏,触发限频,造成困扰在Slack节点上设置
executeOnce: true
,在上游构建汇总内容
两个分支均到达
Respond to Webhook
响应两次,下游调用方看到错误在响应节点前合并分支,或确保只有一个分支到达响应节点
Reset
Loop Over Items
无明确终止条件
无限循环,n8n消耗内存直到执行被终止始终设置明确的终止条件。分页API优先使用HTTP分页
在同一工作流中嵌套
Loop Over Items
运行时出错,但验证通过将内部循环移到子工作流中,在外层迭代时调用。详情请查看
n8n-subworkflows-official
mode: 'each'