Quartz 4.0.0-alpha.1

Prefix Reserved
This is a prerelease version of Quartz.
dotnet add package Quartz --version 4.0.0-alpha.1
                    
NuGet\Install-Package Quartz -Version 4.0.0-alpha.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Quartz" Version="4.0.0-alpha.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Quartz" Version="4.0.0-alpha.1" />
                    
Directory.Packages.props
<PackageReference Include="Quartz" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Quartz --version 4.0.0-alpha.1
                    
#r "nuget: Quartz, 4.0.0-alpha.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Quartz@4.0.0-alpha.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Quartz&version=4.0.0-alpha.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Quartz&version=4.0.0-alpha.1&prerelease
                    
Install as a Cake Tool

title: Quartz 4 Quick Start

Welcome to the Quick Start Guide for Quartz.NET. As you read this guide, expect to see details of:

  • Installing Quartz.NET
  • Configuring Quartz to your own particular needs
  • Running a first job, in a console application and under a host

Install

dotnet add package Quartz

That is everything a scheduler needs. Dependency injection, hosting and System.Text.Json serialization are part of the core package — 3.x shipped them as Quartz.Extensions.DependencyInjection, Quartz.Extensions.Hosting and Quartz.Serialization.Json.

The optional packages, added the same way when you want them:

Package For
Quartz.Serialization.Newtonsoft persisting with Newtonsoft.Json instead of System.Text.Json
Quartz.Jobs the ready-made jobs — file scanning, sending mail, running a process
Quartz.Plugins history logging, XML/JSON schedule files, the interrupt monitor
Quartz.AspNetCore health checks and the HTTP API
Quartz.Dashboard the web dashboard

Configuration

Quartz is configured with strongly typed options. An option has the same name in code and in configuration files, so there is one vocabulary to learn.

In an application with a host

Most applications register Quartz into their service collection:

builder.AddQuartz(q =>
{
    q.ConfigureScheduler(options => options.InstanceName = "MyScheduler");

    // default max concurrency is 10
    q.UseDefaultThreadPool(maxConcurrency: 5);

    q.UsePersistentStore(store =>
    {
        // there are other databases supported too
        store.UseSqlServer("my connection string");
        store.UseClustering();

        // System.Text.Json is built in; the Newtonsoft one is a package away
        store.UseSystemTextJsonSerializer();

        store.Configure(options =>
        {
            // store job data as strings, which avoids surprises when a serialized
            // type changes shape later
            options.StoreJobDataAsStrings = true;
        });
    });

    // reads jobs and triggers from XML; requires the Quartz.Plugins package
    q.UseXmlSchedulingConfiguration(x =>
    {
        x.Files.Add("~/quartz_jobs.xml");
        x.FailOnFileNotFound = true;
        x.FailOnSchedulingError = true;
    });
});

builder.AddQuartzHostedService(options => options.WaitForJobsToComplete = true);

The hosted service starts the scheduler with the application and shuts it down with it.

Without a host

Console applications and tests build a scheduler directly. The configuration API is the same, and the whole chain is one expression:

IScheduler scheduler = await QuartzSchedulerBuilder.Create()
    .ConfigureScheduler(options => options.InstanceName = "MyScheduler")
    .UseDefaultThreadPool(maxConcurrency: 5)
    .UseInMemoryStore()
    .BuildScheduler();

await scheduler.Start();

From configuration files

Settings can come from appsettings.json, or anywhere else IConfiguration reads from, using the same names:

{
  "Quartz": {
    "Scheduler": { "InstanceName": "MyScheduler" },
    "ThreadPool": { "MaxConcurrency": 3 }
  }
}

builder.AddQuartz(...) reads that section by itself. On a bare IServiceCollection, name it:

services.AddQuartz(configuration.GetSection("Quartz"));

Flat quartz.* keys from earlier versions are still accepted and mean the same thing. Full details are in the Quartz Configuration Reference.

The scheduler created by this configuration has the following characteristics:

  • Scheduler:InstanceName - This scheduler's name will be "MyScheduler".
  • ThreadPool:MaxConcurrency - Maximum of 3 jobs can be run simultaneously (default is 10).
  • No job store is configured, so Quartz's data — jobs, triggers and their state — is held in memory rather than in a database.

Even if you intend to use a database, it is worth getting Quartz working with the in-memory store first, before adding a second thing that can go wrong.

::: tip Actually you don't need to define these properties if you don't want to, Quartz.NET comes with sane defaults :::

A first console application

The following program builds a scheduler with the default configuration, starts it, and shuts it down:

Program.cs

using Quartz;

// Build a scheduler with the default configuration
IScheduler scheduler = await QuartzSchedulerBuilder.Create().BuildScheduler();

// and start it off
await scheduler.Start();

// some sleep to show what's happening
await Task.Delay(TimeSpan.FromSeconds(10));

// and last shut down the scheduler when you are ready to close your program
await scheduler.Shutdown();

Your application terminates once there is no code left to execute after scheduler.Shutdown(): a running scheduler does not keep the process alive on its own. Block explicitly — or use the host, which does the blocking for you — if the scheduler should keep running.

Run it now and nothing happens: ten seconds pass and the program ends. Let us add some logging.

Adding logging

Quartz logs through Microsoft.Extensions.Logging. Under a host it uses whatever the application already configured, and there is nothing to do. A console application with no host tells Quartz where to log by handing LogProvider a logger factory:

using Microsoft.Extensions.Logging;
using Quartz.Diagnostics;

ILoggerFactory loggerFactory = LoggerFactory.Create(logging => logging
    .SetMinimumLevel(LogLevel.Debug)
    .AddSimpleConsole(options =>
    {
        options.SingleLine = true;
        options.TimestampFormat = "HH:mm:ss ";
    }));

LogProvider.SetLogProvider(loggerFactory);

Trying out the application and adding jobs

Now starting the application says considerably more:

12:51:10 info: Quartz.Core.QuartzScheduler[0] Quartz Scheduler created
12:51:10 info: Quartz.Impl.RAMJobStore[0] RAMJobStore initialized.
12:51:10 info: Quartz.Impl.DefaultSchedulerFactory[0] Quartz Scheduler 4.0.0.0 - 'MyScheduler' with instanceId 'NON_CLUSTERED' initialized
12:51:10 info: Quartz.Impl.DefaultSchedulerFactory[0] Using thread pool 'Quartz.Impl.DefaultThreadPool', size: 10
12:51:10 info: Quartz.Impl.DefaultSchedulerFactory[0] Using job store 'Quartz.Impl.RAMJobStore', supports persistence: False, clustered: False
12:51:10 info: Quartz.Core.QuartzScheduler[0] Scheduler MyScheduler_$_NON_CLUSTERED started.

We need a simple test job to try the scheduler out; let's create a HelloJob that greets the console.

public sealed class HelloJob : IJob
{
    public async ValueTask Execute(IJobExecutionContext context, CancellationToken cancellationToken = default)
    {
        await Console.Out.WriteLineAsync("Greetings from HelloJob!");
    }
}

To do something interesting, add code just after Start(), before the Task.Delay:

// define the job and tie it to our HelloJob class
IJobDetail job = JobBuilder.Create<HelloJob>()
    .WithIdentity("job1", "group1")
    .Build();

// Trigger the job to run now, and then repeat every 10 seconds
ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("trigger1", "group1")
    .StartNow()
    .WithSimpleSchedule(x => x
        .WithInterval(TimeSpan.FromSeconds(10))
        .RepeatForever())
    .Build();

// Tell Quartz to schedule the job using our trigger
await scheduler.ScheduleJob(job, trigger);

// several triggers for one job go together, in one call
// await scheduler.ScheduleJob(job, [trigger1, trigger2], new ScheduleJobOptions { Replace = true });

The complete console application now looks like this:

using Microsoft.Extensions.Logging;

using Quartz;
using Quartz.Diagnostics;

ILoggerFactory loggerFactory = LoggerFactory.Create(logging => logging
    .SetMinimumLevel(LogLevel.Debug)
    .AddSimpleConsole(options =>
    {
        options.SingleLine = true;
        options.TimestampFormat = "HH:mm:ss ";
    }));

LogProvider.SetLogProvider(loggerFactory);

// Build a scheduler with the default configuration
IScheduler scheduler = await QuartzSchedulerBuilder.Create().BuildScheduler();

await scheduler.Start();

IJobDetail job = JobBuilder.Create<HelloJob>()
    .WithIdentity("job1", "group1")
    .Build();

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("trigger1", "group1")
    .StartNow()
    .WithSimpleSchedule(x => x
        .WithInterval(TimeSpan.FromSeconds(10))
        .RepeatForever())
    .Build();

await scheduler.ScheduleJob(job, trigger);

// let it run for a while
await Task.Delay(TimeSpan.FromSeconds(60));

await scheduler.Shutdown();

public sealed class HelloJob : IJob
{
    public async ValueTask Execute(IJobExecutionContext context, CancellationToken cancellationToken = default)
    {
        await Console.Out.WriteLineAsync("Greetings from HelloJob!");
    }
}

Creating and initializing the database

To use SQL persistence, and features such as clustering that depend on it, create a database for Quartz and then create its tables and indexes.

The DDL scripts are in the Quartz.NET repository, one per database. Upgrading a schema created by an earlier version is a different script — see Database Schema Changes. What the tables hold is described in Database.

Now go have some fun exploring Quartz.NET. Continue with the tutorial.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (907)

Showing the top 5 NuGet packages that depend on Quartz:

Package Downloads
Quartz.Extensions.DependencyInjection

Quartz.NET Microsoft.Extensions.DependencyInjection integration; Quartz Scheduling Framework for .NET

Quartz.Serialization.Json

Quartz.NET JSON Serialization Support; Quartz Scheduling Framework for .NET

Quartz.AspNetCore

Quartz.NET ASP.NET Core integration; Quartz Scheduling Framework for .NET

MassTransit.Quartz

MassTransit Quartz.NET scheduler support; MassTransit provides a developer-focused, modern platform for creating distributed applications without complexity.

WasmAI.AutoGenerator

is a powerful code-generation library for .NET 8 that automates the scaffolding of backend components like models, services, controllers, and more—based on a flexible folder configuration.

GitHub repositories (107)

Showing the top 20 popular GitHub repositories that depend on Quartz:

Repository Stars
bitwarden/server
Bitwarden infrastructure/backend (API, database, Docker, etc).
abpframework/abp
Open-source web application framework for ASP.NET Core! Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET. Provides the fundamental infrastructure, cross-cutting-concern implementations, startup templates, application modules, UI themes, tooling and documentation.
kgrzybek/modular-monolith-with-ddd
Full Modular Monolith application with Domain-Driven Design approach.
aspnetboilerplate/aspnetboilerplate
ASP.NET Boilerplate - Web Application Framework
RayWangQvQ/BiliBiliToolPro
B 站(bilibili)自动任务工具,支持docker、青龙、k8s等多种部署方式。全面拥抱AI。敏感肌也能用。
MassTransit/MassTransit
Distributed Application Framework for .NET
anjoy8/Blog.Core
💖 ASP.NET Core 8.0 全家桶教程,前后端分离后端接口,vue教程姊妹篇,官方文档:
Jeric-X/SyncClipboard
跨平台剪贴板同步、历史记录管理工具 / Cross-platform cipboard syncing, history management tool
dotnetcore/Util
Util是一个.Net平台下的应用框架,旨在提升中小团队的开发能力,由工具类、分层架构基类、Ui组件,配套代码生成模板,权限等组成。
dotnetcore/WTM
Use WTM to write .netcore app fast !!!
cq-panda/Vue.NetCore
(已支持sqlsugar).NetCore、.Net6、Vue2、Vue3、Vite、TypeScript、Element plus+uniapp前后端分离,全自动生成代码;支持移动端(ios/android/h5/微信小程序。http://www.volcore.xyz/
Ombi-app/Ombi
Want a Movie or TV Show on Plex/Emby/Jellyfin? Use Ombi!
oskardudycz/EventSourcing.NetCore
Examples and Tutorials of Event Sourcing in .NET
Arcenox-co/TickerQ
TickerQ is a fast, reflection-free background task scheduler for .NET built with source generators, EF Core integration, cron + time-based execution, and a real-time dashboard.
kgrzybek/sample-dotnet-core-cqrs-api
Sample .NET Core REST API CQRS implementation with raw SQL and DDD using Clean Architecture.
BookerLiu/GeekDesk
🔥小巧、美观的桌面快速启动工具 Small, beautiful desktop quickstart management tool with integrated Everything search
liukuo362573/YiShaAdmin
基于 .NET Core MVC 的权限管理系统,代码易读易懂、界面简洁美观
Cleanuparr/Cleanuparr
Advanced download manager for the Servarr ecosystem
BrighterCommand/Brighter
A framework for building messaging apps with .NET and C#.
phongnguyend/Practical.CleanArchitecture
Full-stack .Net 10 Clean Architecture (Microservices, Modular Monolith, Monolith), Blazor, Angular 22, React 19, Vue 3.5, BFF with YARP, NextJs 16, Domain-Driven Design, CQRS, SOLID, Asp.Net Core Identity Custom Storage, OpenID Connect, EF Core, OpenTelemetry, SignalR, Background Services, Health Checks, Rate Limiting, Clouds (Azure, AWS, GCP), ...
Version Downloads Last Updated
4.0.0-alpha.1 33 8/22/2026
3.19.1 432,098 7/26/2026
3.19.0 50,008 7/24/2026
3.18.2 780,685 6/27/2026
3.18.1 2,330,637 4/25/2026
3.18.0 590,247 4/11/2026
3.17.1 377,809 4/3/2026
3.17.0 376,555 3/29/2026
3.16.1 1,469,121 3/4/2026
3.16.0 2,494,504 3/1/2026
3.15.1 7,109,367 10/26/2025
3.15.0 4,505,219 8/3/2025
3.14.0 10,223,394 3/8/2025
3.13.1 14,648,013 11/2/2024
3.13.0 6,766,889 8/10/2024
3.12.0 720,902 8/3/2024
3.11.0 2,425,745 7/7/2024
3.10.0 730,367 6/26/2024
3.9.0 3,634,599 5/9/2024
3.8.1 6,475,917 2/17/2024
Loading failed