Table of Contents

Class QuartzSchedulerOptions

Namespace
Quartz
Assembly
Quartz.dll

Strongly typed configuration for the scheduler itself.

public sealed class QuartzSchedulerOptions
Inheritance
QuartzSchedulerOptions
Inherited Members

Remarks

Binds from the Scheduler section of the Quartz configuration, and is the typed replacement for the quartz.scheduler.* property keys.

Fields

DefaultInstanceId

The value for InstanceId that marks a scheduler as not participating in a cluster.

public const string DefaultInstanceId = "NON_CLUSTERED"

Field Value

string

DefaultInstanceName

The default value for InstanceName.

public const string DefaultInstanceName = "QuartzScheduler"

Field Value

string

Properties

BatchTriggerAcquisitionFireAheadTimeWindow

How far past the current time a trigger may fire in order to be included in the current acquisition batch.

public TimeSpan BatchTriggerAcquisitionFireAheadTimeWindow { get; set; }

Property Value

TimeSpan

Remarks

The other half of MaxBatchSize. At the default of Zero a batch holds the triggers already due, or due at the same instant as the first, and nothing else. Widening it fires triggers early by up to this much, which is what the wider batch costs.

Context

Values seeded into SchedulerContext when the scheduler is created.

public Dictionary<string, string> Context { get; }

Property Value

Dictionary<string, string>

Remarks

Replaces the quartz.context.key.* property keys.

DefaultMisfireHandling

The misfire instruction a trigger is given when nobody stated one for it. Defaults to SmartPolicy, which is what every trigger did before there was a default.

public DefaultMisfireHandling DefaultMisfireHandling { get; set; }

Property Value

DefaultMisfireHandling

Remarks

Mapped to each trigger family's own instruction when the trigger is scheduled; the table is on DefaultMisfireHandling. An instruction a builder, an attribute, the JSON schedule or a stored or deserialized trigger stated — SmartPolicy included — is left alone.

Resolved as the trigger is stored rather than as it misfires, so it changes no trigger already in a store, and the stored instruction is the one every node, an older one included, follows. Each node of a cluster applies its own default to what it schedules, so set the same one on every node. Replaces nothing: the quartz.scheduler.defaultMisfireHandling property key is new with it.

DefaultTimeZone

The time zone a cron, calendar-interval, daily time-interval or recurrence trigger is given when nobody stated one for it. Defaults to null, which leaves such a trigger in Local, as every trigger was before there was a default.

public TimeZoneInfo? DefaultTimeZone { get; set; }

Property Value

TimeZoneInfo

Remarks

A zone a builder's InTimeZone, a cron expression, an attribute, the JSON or XML schedule, or a stored or deserialized trigger stated - Local included - is left alone. A trigger an HttpScheduler sends is deserialized on the host, so it keeps the zone the client gave it, and the host's default does not apply.

Resolved as the trigger is stored, before its first fire time is computed, so the stored zone is explicit, it changes no trigger already in a store, and every node, an older one included, reads the same zone. Each node of a cluster applies its own default to what it schedules, so set the same one on every node.

A configuration file writes it as an id FindById(string) resolves, IANA or Windows: Quartz:Scheduler:DefaultTimeZone, or the flat quartz.scheduler.defaultTimeZone key. An id the system cannot resolve fails the scheduler's start.

GenerateInstanceId

When true, InstanceId is generated at startup by the registered IInstanceIdGenerator instead of being taken from InstanceId.

public bool GenerateInstanceId { get; set; }

Property Value

bool

IdleWaitTime

How long the scheduler waits before re-querying the job store when it finds no triggers to fire.

public TimeSpan IdleWaitTime { get; set; }

Property Value

TimeSpan

Remarks

Must be at least one second. Lower values increase job store load for little benefit.

InstanceId

The id of the scheduler, which must be unique within a cluster.

public string InstanceId { get; set; }

Property Value

string

Remarks

Leave at the default to opt out of clustering. Set GenerateInstanceId instead of assigning a literal id when the id should be derived at startup. A clustered scheduler left at the default derives one: UseClustering() and the quartz.jobStore.clustered key turn GenerateInstanceId on unless an id was chosen.

InstanceName

The name of the scheduler, which must be unique within the process.

public string InstanceName { get; set; }

Property Value

string

MaxBatchSize

The maximum number of triggers the scheduler acquires in a single batch, or 0 to let the scheduler choose.

public int MaxBatchSize { get; set; }

Property Value

int

Remarks

Defaults to 0, automatic, which is resolved when the scheduler is built:

StoreBatch
Persistent, clustered or notthe thread pool's size
In memory1

On a database a round is round trips and a commit, so taking every trigger already due in one round is cheaper per firing (#3824 measured 128.7 firings a second against 87.6). On a cluster a batch above one also takes the cluster-wide TRIGGER_ACCESS row lock on every round, including rounds that acquire nothing, and still pays: two nodes drained a backlog 1.8 times as fast as at one, and four nodes 1.5 times (#3900). The in-memory store stays at one because its round is a monitor rather than a round trip, and a batch there measured faster for repeating triggers but slower for a burst of one-offs (#3862). An explicit value always wins; 1 is 4.2's behaviour.

This is only the upper bound. The store ends a batch at the later of now and the first trigger's fire time, plus BatchTriggerAcquisitionFireAheadTimeWindow. At the default window of Zero a batch takes every trigger already due and nothing that is not, so nothing fires early; widening the window also batches triggers due shortly after the first, and fires them early by up to that much.

Must not exceed MaxConcurrency: triggers acquired beyond the number of threads there are to run them on are held by this node, unfireable by any other, until the pool drains. The automatic value never does.

PropagateTraceContext

Whether the scheduler records the trace context of the call that scheduled a trigger, so that the firing links back to it. On by default.

public bool PropagateTraceContext { get; set; }

Property Value

bool

Remarks

A scheduled job runs minutes, hours or days after the call that asked for it, quite possibly on another node. With this on, a scheduling call made inside an activity leaves the W3C traceparent on the trigger — under TraceParent and TraceState — and the firing's Quartz.Job.Execute span carries an ActivityLink to it. A link and not a parent: the firing is its own trace root, because a trace spanning the wait would be a trace nothing could display.

Turn it off to keep the two reserved keys out of trigger data entirely — for a store whose rows are read by something that does not expect them, or where the extra two entries per trigger are not worth what they buy. Nothing else changes: the execute span is emitted either way.

RecordExceptionSpanEvents

Whether a failed span records the exception as an exception span event, or null to follow the OTEL_SEMCONV_EXCEPTION_SIGNAL_OPT_IN environment variable. Records them by default.

public bool? RecordExceptionSpanEvents { get; set; }

Property Value

bool?

Remarks

OpenTelemetry deprecated span events in 2026, exception events included, in favour of exceptions emitted as logs. Quartz already logs each of these exceptions through ILogger while the span is current, so false removes only the copy on the span. The span still ends in error, with the exception's message as the status description and its type as error.type.

Unset, the environment decides: OTEL_SEMCONV_EXCEPTION_SIGNAL_OPT_IN=logs stops the events, and logs/dup or no value keeps them. A value set here wins over the variable.

RefusedExecutionGroups

The execution groups this node never acquires or misfire-handles; empty means none.

public List<string> RefusedExecutionGroups { get; }

Property Value

List<string>

Remarks

The same spellings as ServedExecutionGroups, and exclusive with it. A list that omits _ still serves ungrouped triggers. Replaces the quartz.scheduler.refusedExecutionGroups property key, whose value is comma-separated.

ServedExecutionGroups

The execution groups this node acquires and misfire-handles; empty means every group.

public List<string> ServedExecutionGroups { get; }

Property Value

List<string>

Remarks

An entry is a group name, or _ (or null) for the triggers that carry no execution group — the spelling an execution limit's key uses for the same bucket. A list that omits _ does not serve ungrouped triggers. Names are compared ordinally in memory and by the column's collation in SQL; there is no wildcard or prefix form, and * is refused.

Exclusive with RefusedExecutionGroups: a node lists the groups it serves or the groups it refuses, never both. A trigger in a group no live node serves waits, unmodified, until a serving node arrives; the health check and the dashboard report such a group. Get-only, like every collection on a Quartz options type: add to it. Replaces the quartz.scheduler.servedExecutionGroups property key, whose value is comma-separated.

ShutdownJobInterruption

When a shutting-down scheduler signals cancellation to the jobs still executing.

public ShutdownJobInterruption ShutdownJobInterruption { get; set; }

Property Value

ShutdownJobInterruption

Remarks

This was two independent booleans, one for a shutdown that waits for jobs and one for a shutdown that does not. They were never independent: together they answered a single four-way question, and the pair could be set to a combination — both false — that spelled the default in two ways.