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

Quartz.NET 4.0 is released. It targets net10.0, the container builds the scheduler, and a public surface that had accumulated for a decade has been read, argued over and trimmed.

It is a major version with extensive breaking changes and a mandatory schema migration. Nothing here is a surprise if you have read the migration guide, which lists every one of them with before and after, and carries an ordered runbook for upgrading a running deployment.

  • What 4.0 is
  • Before you upgrade
  • Where to start

What 4.0 is

  • net10.0 only. There is no netstandard2.0 build and no Full Framework .config support. If you need either, 3.x is maintained.
  • The container builds the scheduler. Dependency injection and hosting are in the core Quartz package, quartz.config is no longer read, and the process-global singletons are gone. Flat quartz.* keys still work — they are translated into typed options, which have the same names in code and in appsettings.json.
  • Asynchronous throughout. Every public Task became a ValueTask, every async member ends with a cancellation token, and IJob.Execute takes one — so a job that ignores a shutdown is a compiler warning rather than a mystery.
  • Listings became queries. QueryJobs and QueryTriggers answer with a page of headers that already carry what a listing needs, so a UI over a large schema stops paying for the whole schema. The old call shapes remain as extension methods.
  • New ways to say when. Recurrence triggers take an RFC 5545 rule, the cron parser reads Unix five-field expressions beside Quartz's own, and TriggerState.Executing tells you a trigger's job is running anywhere in the cluster.
  • Operable out of the box. An HTTP API, a dashboard, a health check, OpenTelemetry spans and metrics, and an event id on every log message. Both web surfaces refuse to start unless something authorizes them: either can schedule any job type by name.
  • Faster per firing than 3.20 — 1.5× faster and 2.4× less allocation on PostgreSQL, faster with 21 % less allocation in memory. The operations guide has the numbers and what was run to get them.

Before you upgrade

  • Run the schema migration. database/migrations/4.0/schema_30_to_40_upgrade_<database>.sql is the mandatory half and is safe to apply while 3.x nodes are still running; schema_30_to_40_indexes_<database>.sql is the half that waits until the last one is gone. A 4.0 node against an unmigrated schema refuses to start, and says which column is missing.
  • Daylight saving fire times changed. Interval cron expressions fire through both halves of a repeated fall-back hour instead of skipping one, and CalendarIntervalTrigger with PreserveHourOfDayAcrossDaylightSavings no longer drifts in zones whose offset is not a whole hour. Review any schedule that crosses a transition.
  • The 3.20 → 4.0 upgrade is rehearsed on every dialect in CI, against rows a released 3.20 wrote, and by hand on a running two-node cluster on PostgreSQL and SQL Server. The production checklist is the short form of what that found.

Where to start

The quick start is one package and a few lines, and the tutorial is the guided tour from there to a cluster.

Thank you to everyone who filed an issue, sent a pull request or ran a pre-release and told us what broke. If something you relied on is gone, open an issue — decisions taken during 4.0's development can be reopened.

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