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
    • Configuration Reference
    • JSON Configuration
    • Cron Expression Reference
    • Multi-Tenancy
    • Frequently Asked Questions
    • Best Practices
    • Before You Go Live
    • Operating a Cluster
    • Log Events
    • Tenancy Patterns
    • Database Schema
    • Database Schema Changes
    • Migration Guide
    • Troubleshooting
  • How To's
    • One-Off Job
    • Rescheduling Jobs
    • Retrying Failed Jobs
    • Multiple Triggers
    • Job Template
    • Running Quartz under Aspire
    • Quartz.NET with Wolverine
    • 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
    • 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

This release concentrates on performance and bringing support for standard integrations. Quartz 3.1 supports netstandard2.0 and net461 targets (for integrations they may be different).

  • New Integrations
    • Support for ASP.NET Core Dependency Injection and Hosted Services
    • OpenTelemetry Integration
  • Database
    • Better Indexes for SQL Server and smarter parametrized queries
    • Bug fix for cluster locking
    • Microsoft.Data.SqlClient as SQL Server connection library
    • Upgrade MySqlConnector to 1.0 (namespace has changed)
  • Known Issues
  • GitHub Issues

New Integrations

Support for ASP.NET Core Dependency Injection and Hosted Services

New NuGet packages ASP.NET Core Integration and Quartz.Extensions.DependencyInjection finally bring built-in support for integrating Quartz.NET with reliable manner with the Microsoft DI container and hosted services infrastructure.

The best resource the see the new DI integration in progress is to head to the example ASP.NET Core application.

I would like to thank both Facundo Glaeser and Lewis Zou for working with the new integration packages and their logistics.

OpenTelemetry Integration

New experimental NuGet package Quartz.OpenTelemetry.Instrumentation brings support for emerging OpenTelemetry standard.

First version of integration is able transmit job execution (Started, Ended, Exception) information to exporters. With this infrastructure is should also be easier to implement job history using battle-tested log backends for storing data. The example ASP.NET Core application integrates with Jaeger and transmits this data.

Database

Better Indexes for SQL Server and smarter parametrized queries

A big change on the persistent store side is that now SQL queries use parametrized scheduler name, which allows database server to reuse query plans and use indexes more optimally. This will help especially clusters which have large number of nodes. The SQL server indexes were also revisited and their amount reduced by using smarter covering indexes.

See the updated create index definition for more details.

Tips

You need to re-run the index script to take advantage of changes, this will drop old indexes and rebuild/create new ones, it can be time-consuming!

Bug fix for cluster locking

There is also a very important bug fix present for lock handling on retries. There was a possibility for a deadlock in cluster's database lock handling in some situations.

Microsoft.Data.SqlClient as SQL Server connection library

Quartz now uses Microsoft.Data.SqlClient as the connection library for SQL Server as it's the one going to get new features. It is dependency for Quartz library (for now) so you shouldn't need to do any manual install steps.

Upgrade MySqlConnector to 1.0 (namespace has changed)

You need to use the latest MySqlConnector 1.0.0 in order to use with default Quartz configuration. As the namespace for library has changed it's not backwards compatible. If you need to use the old version, you should manually register DB provider with the old details.

Known Issues

No known issues. Documentation might require additions and community contributions are welcomed. Edits should be easy now with the new publishing framework.

GitHub Issues

BREAKING CHANGES

  • minimum supported .NET Full Framework is now 4.6.1
  • changed SQL commands format in Quartz.Impl.AdoJobStore.JobStoreSupport (see also #818). Affected are only schedulers that use customized configurations of SQL commands in Quartz.Impl.AdoJobStore.JobStoreSupport, e.g. SelectWithLockSQL. Migration example:
<!-- Quartz <=3.0.7 -->
<item key="quartz.jobStore.selectWithLockSQL">SELECT * FROM {0}LOCKS WITH (UPDLOCK,ROWLOCK) WHERE SCHED_NAME = {1} AND LOCK_NAME = @lockName</item>
<!-- Quartz >=3.1.0 -->
<item key="quartz.jobStore.selectWithLockSQL">SELECT * FROM {0}LOCKS WITH (UPDLOCK,ROWLOCK) WHERE SCHED_NAME = @schedulerName AND LOCK_NAME = @lockName</item>

NEW FEATURE

  • Microsoft DI integration via package Quartz.Extensions.DependencyInjection (also allows bridging to Microsoft Logging)
  • DI configuration now supports adding scheduler, job and trigger listeners (#877)
  • DI configuration now processes appsettings.json section "Quartz" looking for key value pairs (#877)
  • Add diagnostics source and OpenTelemetry support (#901)
  • Use Microsoft.Data.SqlClient as SQL Server connection library (#839)
  • ASP.NET Core / Hosting integration and health checks via revisited NuGet package Quartz.AspNetCore (thank you zlzforever for contributing the work)
  • Introduced a config parameter ClusterCheckinMisfireThreshold (#692)
  • Giving meaningful names to examples folders (#701)
  • Added search patterns/sub directory search to directory scanner job (#411, #708)
  • Fluent interface for scheduler configuration (#791)
  • Support every nth week in cron expression (#790)
  • Enable SQLite job store provider for NetStandard (#802)
  • Add configurable params for StdRowLockSemaphore for Failure obtaining db row lock
  • SchedName added to queries as sql parameter (#818)
  • Server, example and test projects upgraded to user .NET Core 3.1
  • Nullable reference type annotations have been enabled
  • Symbols are now provided as a separate NuGet symbol package (snupkg)
  • SQL Server indexes have been fine-tuned, redundancies were removed and you can follow the current scripts to update to latest version of them
  • Upgrade MySqlConnector to 1.0 (namespace has changed) (#890)
  • Support Microsoft.Extensions.Logging.Abstractions (#756)
  • Support Microsoft.Data.SQLite with full framework (#893)
  • Support custom calendar JSON serialization (#697)
  • DI configuration now supports adding scheduler, job and trigger listeners (#877)
  • DI configuration now processes appsettings.json section "Quartz" looking for key value pairs (#877)
  • Use Microsoft.Data.SqlClient as SQL Server connection library (#839)

FIXES

  • Allow binary serialization for DirectoryScanJob data (#658)
  • LibLog - Fixed NLog + Log4net callsite. Added support for NLog structured logging. Optimized Log4net-logger (#705)
  • Upgrade LibLog to latest version (#749)
  • RAMJobStore performance improvements (#718, #719, #720)
  • General performance improvements (#725, #723, #727)
  • GetTimeBefore() and GetFinalFireTime() should throw NotImplementedException instead of returning null (#731)
  • Switch to official TimeZoneConverter NuGet package (#739)
  • Remove invalid TimeSpanParseRule.Days (#782)
  • Update tables_sqlServer.sql to follow current SQL syntax and structures (#787)
  • Fix China Standard Time mapping in TimeZoneUtil.cs (#765)
  • Release BLOCKED triggers in ReleaseAcquiredTrigger (#741 #800)
  • DailyTimeIntervalTrigger failed to set endingDailyAfterCount = 1
  • CronTrigger: cover all valid misfire policies, and provide a sensible default and logging when seeing an invalid one
  • Remove internal dependencies from examples (#742)
  • Properly assign MaxConcurrency in CreateVolatileScheduler (#726)
  • Fix potential scheduler deadlock caused by changed lock request id inside ExecuteInNonManagedTXLock (#794)
  • Ensure NuGet.exe is part of produced zip to ensure build works (#881)
  • JobDataMap with enum values persisted as JSON can now be set back to job members via PropertySettingJobFactory (#770)
  • Ensure GetScheduleBuilder for triggers respects IgnoreMisfirePolicy (#750)
  • Remove cron expression validation from XML schema and rely on CronExpression itself (#729)
See download and installation instructions.
Help us by improving this page!
Last Updated: 9/3/26, 1:13 PM
Contributors: Marko Lahma, Claude Fable 5.1