misfire_grace_seconds and a stale slot is recorded as missed in history instead of firing a no-longer-useful run.
Quick Start
1
Set a grace window
Set
misfire_grace_seconds so a stale slot after downtime is recorded rather than fired.2
Same job in YAML
3
Leave it unset for the old behaviour
Leaving
misfire_grace_seconds unset (or None) preserves the pre-existing behaviour — a missed occurrence still coalesces into one fire on recovery.How It Works
On recovery the store looks at each due job, computes the epoch of the occurrence it is firing for, and either fires (within grace / first run) or recordsmissed (past grace).
What The User Sees
Silence, not a stale ping — a broken window shows up as amissed row in run history so an operator can spot the gap on the same page they read successes and failures.
Kinds — how the “occurrence” is derived
scheduled_instant() derives the recovered slot per Schedule.kind, so you can reason about which fire is being suppressed.
Configuration Options
Full field reference for the job dataclass
All run status values and history fields
The new
RunRecord.status value.
Common Patterns
A daily brief tolerates a short delay but not a multi-hour one.Best Practices
Set the grace to the usefulness window
Set the grace to the usefulness window
The grace is “how late can this slot still be useful?” — a daily 07:00 brief probably tolerates 10 minutes but not 6 hours; an hourly poll of live data might tolerate 30 seconds.
Leave it None when 'late is better than never'
Leave it None when 'late is better than never'
None (the default) is the right choice when a coalesced late fire is still valuable — the previous behaviour is preserved byte-for-byte.Read a cluster of missed rows as a downtime marker
Read a cluster of missed rows as a downtime marker
A cluster of
missed rows across jobs is a downtime marker — combine it with Scheduler Incidents so a broken schedule and a broken job are both surfaced.Write a number, not a string
Write a number, not a string
_coerce_optional_float will accept "3600" in a hand-edited config, but the intended form is unquoted (misfire_grace_seconds: 3600). Non-numeric junk fails safe to “no misfire policy”.Related
Cross-run notepad the scheduler already persists
Alert once when a scheduled job breaks
Silence-when-unchanged sibling — declarable monitor spec
The async runner that observes the policy

