Quartz.NETQuartz.NET
Home
Features
Blog
Discussions
NuGet
GitHub
Home
Features
Blog
Discussions
NuGet
GitHub
  • Getting Started

    • Overview
    • Quartz 4 Quick Start
    • Tutorial
      • Using Quartz
      • Jobs And Triggers
      • More About Jobs & JobDetails
      • Job Data
      • More About Triggers
      • Querying Jobs and Triggers
      • Simple Triggers
      • Cron Triggers
      • RecurrenceTrigger
      • Time and TimeProvider
      • Trigger and Job Listeners
      • Scheduler Listeners
      • Job Execution Middleware
      • Job Stores
      • Configuration, Resource Usage and Building a Scheduler
      • Building a Scheduler Without a Host
      • Clustering
      • Execution Groups
      • Node Affinity (Preferred Node)
      • Testing
      • Compile-Time Checks
      • Declaring Jobs with Attributes
      • Delegate Jobs
    • Configuration Reference
    • JSON Configuration
    • Cron Expression Reference
    • Multi-Tenancy
    • Comparison
    • Frequently Asked Questions
    • Best Practices
    • Before You Go Live
    • Operating a Cluster
    • Log Events
    • Tenancy Patterns
    • Database Schema
    • Database Schema Changes
    • Migration Guide
    • Troubleshooting
    • API Documentation
  • How To's
    • One-Off Job
    • Rescheduling Jobs
    • Backfill
    • Retrying Failed Jobs
    • Pausing with a Reason
    • Job Continuations
    • Overlap Policy
    • Progress and Execution Logs
    • Job Outcomes
    • Multiple Triggers
    • Job Template
    • Running Quartz under Aspire
    • Quartz.NET with Wolverine
    • Coming from Hangfire
    • Coming from TickerQ
    • Embedding Quartz in a Library
    • Running under an External Leader Election
    • Publishing Trimmed and Native AOT
    • Extending Quartz: what is open, what is closed, and how to ask
    • A Job Store of Your Own
    • A Driver Delegate for a New Database
    • Persisting a Custom Trigger Type
    • A Lock Handler of Your Own
  • Packages

    • Quartz Core Additions

      • Jobs
      • Serialization (System.Text.Json)
      • JSON Serialization
      • Plugins
    • Integrations

      • Aspire Integration
      • ASP.NET Core Integration
      • HTTP API
      • HTTP Client
      • Dashboard
      • Hosted Services Integration
      • Microsoft DI Integration
      • Multiple Schedulers with Microsoft DI
      • Observability
      • Redis Lock Handler
      • TimeZoneConverter Integration
      • Weasel Schema Management
    • 3rd Party Plugins for Quartz
  • Quartz 3.x

    • Getting Started

      • Quartz 3 Quick Start
      • Tutorial
        • Using Quartz
        • Library Overview
        • Jobs And Triggers
        • More About Jobs
        • More About Triggers
        • Execution Groups
        • Node Affinity (Preferred Node)
        • Simple Triggers
        • Cron Triggers
        • RecurrenceTrigger
        • Trigger and Job Listeners
        • Scheduler Listeners
        • Job Stores
        • Tuning the Scheduler
        • Configuration, Resource Usage and SchedulerFactory
        • Advanced (Enterprise) Features
      • Configuration Reference
      • JSON Configuration
      • Multi-Tenancy
      • Frequently Asked Questions
      • Best Practices
      • Tenancy Patterns
      • Troubleshooting
      • API Documentation
      • Database Schema
      • Database Schema Changes
      • Migration Guide
      • Miscellaneous Features
    • How To's

      • One-Off Job
      • Multiple Triggers
      • Job Template
      • Using the CronTrigger
      • Rescheduling Jobs
    • Packages

      • Quartz Core Additions

        • Dashboard
        • Jobs
        • Serialization (System.Text.Json)
        • Serialization (Newtonsoft Json.NET)
        • Plugins
      • Integrations

        • ASP.NET Core Integration
        • Hosted Services Integration
        • Microsoft DI Integration
        • Multiple Schedulers with Microsoft DI
        • OpenTelemetry Integration
        • OpenTracing Integration
        • Redis Lock Handler
        • TimeZoneConverter Integration
      • 3rd Party Plugins for Quartz
  • Old Releases

    • Quartz 2.x
      • Quartz 2 Quick Start
      • Tutorial
        • Lesson 1: Using Quartz
        • Lesson 2: Jobs And Triggers
        • Lesson 3: More About Jobs & JobDetails
        • Lesson 4: More About Triggers
        • Lesson 5: SimpleTrigger
        • Lesson 6: CronTrigger
        • Lesson 7: TriggerListeners and JobListeners
        • Lesson 8: SchedulerListeners
        • Lesson 9: JobStores
        • Lesson 10: Configuration, Resource Usage and SchedulerFactory
        • Lesson 11: Advanced (Enterprise) Features
        • Lesson 12: Miscellaneous Features of Quartz
        • CronTrigger Tutorial
      • Configuration Reference
      • Migration Guide
      • API Documentation
    • Quartz 1.x
      • Tutorial
        • Lesson 1: Using Quartz
        • Lesson 2: Jobs And Triggers
        • Lesson 3: More About Jobs & JobDetails
        • Lesson 4: More About Triggers
        • Lesson 5: SimpleTrigger
        • Lesson 6: CronTrigger
        • Lesson 7: TriggerListeners and JobListeners
        • Lesson 8: SchedulerListeners
        • Lesson 9: JobStores
        • Lesson 10: Configuration, Resource Usage and SchedulerFactory
        • Lesson 11: Advanced (Enterprise) Features
        • Lesson 12: Miscellaneous Features of Quartz
      • API Documentation
  • License

Quartz.NET 4.x targets .NET 10. The quick start gets a scheduler running in a few lines.

Runtime Environments

  • Runs embedded in your application (a console program, a worker service, an ASP.NET Core application), and the application's container builds the scheduler.
  • Several schedulers can run side by side in one process, each with its own store, thread pool and listeners. This is how a host serves several tenants.
  • Any number of processes sharing one database form a cluster that balances work across its nodes and takes over the work of a node that dies.
  • A scheduler can also be built without an application container, or embedded in a library that should not own the host's.

Job Scheduling

Jobs run when a trigger fires. Triggers can combine nearly any of these:

  • at a certain time of day (to the millisecond)
  • on certain days of the week
  • on certain days of the month
  • on certain days of the year
  • not on certain days listed in a registered calendar (such as business holidays)
  • repeated a specific number of times
  • repeated until a specific time/date
  • repeated indefinitely
  • repeated with a delay interval
  • by an RFC 5545 recurrence rule, the rule an iCalendar event repeats on

Cron syntax is the usual way to state the first four. It reads Unix five-field expressions as well as Quartz's own.

  • Jobs and triggers have names and can be organized into named groups.
  • A job is added to the scheduler once and can be registered with several triggers.
  • A trigger carries a priority and a misfire instruction, so a scheduler that falls behind resumes in the order you chose, not the order it reads rows.

Job Execution

  • A job is any .NET class implementing IJob: one Execute method taking the execution context and a CancellationToken.
  • The container constructs the job, so a job takes its dependencies as constructor parameters, and each firing gets its own scope.
  • A firing carries a JobDataMap, whose entries can be bound to the job's properties by name.
  • When a trigger fires, the scheduler notifies any IJobListener and ITriggerListener objects, again after the job has run. A trigger listener can veto a firing before it starts.
  • Middleware wraps execution as ASP.NET Core middleware wraps a request. The shipped middleware retries a failed job and cancels one that overran its [JobTimeout].
  • [DisallowConcurrentExecution] stops a job overlapping itself; [PersistJobDataAfterExecution] keeps its map across firings.
  • Running jobs can be listed and interrupted across the whole cluster, and a trigger reports TriggerState.Executing while its job runs.

Job Persistence

  • Job storage is pluggable through the IJobStore interface.
  • The included ADO.NET job store keeps jobs and triggers in a relational database. SQL Server, PostgreSQL, MySQL, Oracle, SQLite and Firebird each have a driver delegate, and database/ has the schema and migrations for each.
  • The included RAMJobStore keeps jobs and triggers in memory. Nothing persists between runs, but no external database is needed.
  • A store writes JSON, through System.Text.Json or Newtonsoft.Json.
  • The store can join a transaction the application owns, so saving your data and scheduling the job that acts on it commit together.

Clustering

  • Fail-over: another node picks up a dead node's in-flight recoverable work.
  • Load balancing: any node in the cluster may fire any trigger.
  • Node affinity and execution groups control which node runs a job and how many run at once.
  • An external leader can decide which node is active, when something outside Quartz already elects one.

Listeners & Plug-Ins

  • Listener interfaces let applications catch scheduling events to monitor or control job and trigger behavior.
  • Plug-ins add functionality, such as keeping a history of job executions or loading job and trigger definitions from a file.
  • Quartz ships plug-ins and listeners, and ready-made jobs for scanning a directory, sending mail and running a process.

Operating It

  • OpenTelemetry: one activity source and one meter, so firings show up as spans and metrics in whatever you already collect.
  • A health check for the scheduler and, in a cluster, for the node's own check-in.
  • Every log message has an event id, catalogued with its level and template.
  • A dashboard and an HTTP API to inspect and drive a running scheduler, and a client that uses that API as if it were a local IScheduler. Both surfaces refuse to start unless something authorizes them.
  • A production checklist and an operations guide covering rolling upgrades, failover, sizing and backup.
Help us by improving this page!
Last Updated: 10/6/26, 2:13 PM
Contributors: Marko Lahma, Claude Opus 5.5