@n8n/scheduler 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -180,6 +180,42 @@ The filter looks only at the *previous* run, with no stored counter. So any serv
180
180
  in the cluster can compute the next run on its own, and a restart never loses the
181
181
  cadence.
182
182
 
183
+ ## Misfires and late runs
184
+
185
+ A **misfire** is a run that came due while nothing was there to fire it, and is now
186
+ past its grace window (`misfireGraceSeconds`); while still inside that window a late
187
+ instant is simply queued and run late, no policy involved. Once the oldest overdue
188
+ instant is past its window, the job's **misfire policy** decides what happens to the
189
+ rest of the backlog:
190
+
191
+ | Policy | What it does |
192
+ |---|---|
193
+ | `skip` | Records nothing for the backlog; the rule resumes from its next future instant. |
194
+ | `coalesce` | Records one **late run** for that job, standing in for the whole backlog. |
195
+ | `coalesce_owner` | Records one late run for the whole **owner** (see below), across every job that shares it. |
196
+
197
+ A late run is a normal task, queued at the most recent missed instant and
198
+ claimable immediately, so a backlog fires once rather than N times back to back. The
199
+ job's clock advances past the backlog in the same transaction as the late run, so
200
+ no two servers can disagree about what a backlog produced.
201
+
202
+ ### Why `coalesce_owner` exists
203
+
204
+ `coalesce` operates per job, so a Schedule Trigger with several rules on one node
205
+ still produces one late run per rule after downtime, N fires in a row.
206
+ `coalesce_owner` closes that gap: jobs that share an **owner** (`ownerKey`, an opaque
207
+ per-job key the scheduler only compares for equality; in n8n, the trigger node) group
208
+ unconditionally, and only the one with the latest missed instant survives a planning
209
+ pass (ties break on the lowest job id).
210
+
211
+ Grouping only sees jobs claimed together in one pass, so it is best-effort, not a
212
+ guarantee of one fire per owner: a sibling not yet due, or one whose backlog exceeds
213
+ `maxPerJob`, still records its own late run on a later pass.
214
+
215
+ Schedule and poll triggers both use `skip`: it matches what n8n did before the
216
+ durable scheduler, where a missed run was never replayed. Running late is opt-in
217
+ per job, which is where `coalesce` and `coalesce_owner` come in.
218
+
183
219
  ## Durable and distributed
184
220
 
185
221
  Two properties describe the whole design, and everything else follows from them.