Elarion
Scheduling

Overlap & misfire

Control what happens when runs of the same job collide, and when grid schedules fall behind.

Two independent policies govern what happens under load: overlap (a new occurrence is due while one is still running) and misfire (a grid occurrence is observed so late that later ones are also due). They are separate because they answer different questions.

Overlap

Overlap decides what to do when the same job already has an active occurrence. The default is Skip.

PolicyBehavior
SkipDrop a recurring occurrence when the job is already running.
QueueSerialize occurrences of the same job; recurring queued occurrences coalesce so slow jobs do not pile up unlimited waiters.
AllowConcurrentAllow multiple occurrences to run at once, still subject to the global MaxConcurrentExecutions.

Groups

Use Group when different jobs must not overlap each other — for example because they share a mailbox, an export directory, or a third-party API quota:

[ScheduledJob("imports.customerSync", FixedRate = "30s", Group = "imports")]
public async ValueTask SyncCustomersAsync(CancellationToken ct) { /* ... */ }

Bounding concurrency per job

Use MaxConcurrentRuns with AllowConcurrent when a single job may overlap but should still be bounded:

[ScheduledJob(
    "imports.customerSync",
    FixedRate = "30s",
    Overlap = ScheduledJobOverlap.AllowConcurrent,
    MaxConcurrentRuns = 2)]
public async ValueTask SyncCustomersAsync(CancellationToken ct) {
    await importer.SyncAsync(ct);
}

Misfire

Misfire applies only to recurring grid schedules (FixedRate and Cron) when the scheduler observes a due occurrence after one or more later occurrences would also already be due — for example after an in-process pause or a large clock jump. Small timer jitter is not a misfire. FixedDelay schedules have no missed grid slots because the next due time is computed after completion.

PolicyBehavior
FireOnce (default)Run one overdue occurrence, then schedule the next future occurrence and skip the intermediate slots.
SkipDo not run the stale overdue occurrence. Record a skipped outcome with reason misfire, then schedule the next future occurrence.
CatchUpRun missed occurrences in due-time order, respecting normal overlap/concurrency rules. Bounded by Scheduler:MaxMisfireCatchUpRuns; after the cap, the scheduler coalesces to the next future occurrence.

Runtime one-off jobs scheduled through IJobScheduler do not use recurring misfire policy. A one-off job with a due time in the past runs as soon as scheduler capacity is available.

On this page