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

RecurrenceTrigger schedules with an iCalendar RFC 5545 recurrence rule (RRULE). Use it for patterns that CronTrigger and SimpleTrigger cannot express: "every 2nd Monday of the month", "every other week on Monday, Wednesday and Friday", "the last weekday of March each year". It takes a standard RRULE string and computes fire times lazily, without materializing all occurrences.

RRULE Basics

An RRULE is semicolon-separated key-value pairs. FREQ, the base frequency, is required; the other properties refine it:

PropertyDescriptionExample
FREQBase frequency (required)YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY
INTERVALHow often the recurrence repeats (default: 1)INTERVAL=2 (every other)
COUNTMaximum number of times the trigger will fireCOUNT=10
UNTILEnd date/time for the recurrenceUNTIL=20251231T235959Z
BYDAYDays of the week, optionally with ordinalBYDAY=MO,WE,FR or BYDAY=2MO (2nd Monday)
BYMONTHDAYDays of the month (1-31 or -1 to -31)BYMONTHDAY=15 or BYMONTHDAY=-1 (last day)
BYMONTHMonths of the year (1-12)BYMONTH=1,6,12
BYSETPOSPosition within the expanded setBYSETPOS=-1 (last occurrence)
BYHOURHours (0-23)BYHOUR=9,17
BYMINUTEMinutes (0-59)BYMINUTE=0,30
BYSECONDSeconds (0-59)BYSECOND=0
BYWEEKNOWeek numbers (1-53 or -53 to -1)BYWEEKNO=1,26
BYYEARDAYDay of year (1-366 or -366 to -1)BYYEARDAY=1,100,200
WKSTWeek start day (default: MO)WKST=SU

Tips

COUNT and UNTIL are mutually exclusive - you cannot use both in the same RRULE.

Warning

COUNT counts actual firings (TimesTriggered), not recurrence occurrences, which differs from strict RFC 5545 counting:

  • a misfired occurrence that is skipped (e.g. by the DoNothing misfire policy) does not count;
  • an immediate fire caused by the misfire policy (e.g. FireAndProceed) does count.

Examples

Every 2nd Monday of the month at 9:00 AM:

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("monthlyTrigger", "group1")
    .WithRecurrenceSchedule("FREQ=MONTHLY;BYDAY=2MO")
    .StartAt(DateBuilder.Create().InYear(2025).InMonthOnDay(1, 1).AtHourMinuteAndSecond(9, 0, 0).Build())
    .Build();

Every other week on Monday, Wednesday, and Friday:

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("weeklyTrigger", "group1")
    .WithRecurrenceSchedule("FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FR")
    .StartNow()
    .Build();

Last weekday of March each year:

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("yearlyTrigger", "group1")
    .WithRecurrenceSchedule("FREQ=YEARLY;BYMONTH=3;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1")
    .StartNow()
    .Build();

Every day, but only on weekdays (skip weekends):

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("weekdayTrigger", "group1")
    .WithRecurrenceSchedule("FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR")
    .StartNow()
    .Build();

Last day of every month:

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("lastDayTrigger", "group1")
    .WithRecurrenceSchedule("FREQ=MONTHLY;BYMONTHDAY=-1")
    .StartNow()
    .Build();

Every 3 months on the 1st and 15th, limited to 10 occurrences:

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("quarterlyTrigger", "group1")
    .WithRecurrenceSchedule("FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=1,15;COUNT=10")
    .StartNow()
    .Build();

Time Zone Support

Recurrence calculations use the system's local time zone by default. Set another with InTimeZone:

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("trigger1", "group1")
    .WithRecurrenceSchedule("FREQ=MONTHLY;BYDAY=2MO", b => b
        .InTimeZone(TimeZones.FindById("Eastern Standard Time")))
    .StartNow()
    .Build();

DI / Hosted Service Configuration

Under AddQuartz(), use WithRecurrenceSchedule on the trigger:

services.AddQuartz(q =>
{
    q.AddJob<MyJob>(j => j.WithIdentity("myJob"));
    q.AddTrigger(t => t
        .ForJob("myJob")
        .WithIdentity("myTrigger")
        .WithRecurrenceSchedule("FREQ=MONTHLY;BYDAY=2MO")
        .StartNow());
});

RecurrenceTrigger Misfire Instructions

The RecurrenceTriggerMisfireInstruction enum has two trigger-specific instructions, with the same semantics as CronTrigger's, plus IgnoreMisfires, which every family has:

  • RecurrenceTriggerMisfireInstruction.FireAndProceed
  • RecurrenceTriggerMisfireInstruction.DoNothing
  • RecurrenceTriggerMisfireInstruction.IgnoreMisfires

SmartPolicy, the default, resolves to FireAndProceed.

ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("trigger1", "group1")
    .WithRecurrenceSchedule("FREQ=WEEKLY;BYDAY=MO", b => b
        .WithMisfireInstruction(RecurrenceTriggerMisfireInstruction.DoNothing))
    .Build();

When to Use RecurrenceTrigger vs Other Triggers

ScenarioRecommended Trigger
Fixed interval (every 10 seconds)SimpleTrigger
Cron-expressible pattern (every weekday at 9am)CronTrigger
Nth day-of-week in month (2nd Monday)RecurrenceTrigger
Last weekday of a monthRecurrenceTrigger
Every other week on specific daysRecurrenceTrigger
Complex yearly patterns with BYSETPOSRecurrenceTrigger
Calendar interval (every 5 months)CalendarIntervalTrigger

Persistence

Stored inValue
tableQRTZ_SIMPROP_TRIGGERS (existing; no schema change)
RRULE stringSTR_PROP_1 column, max 512 characters
trigger type discriminatorRECUR
Help us by improving this page!
Last Updated: 9/30/26, 6:00 AM
Contributors: Marko Lahma, Claude Opus 5.5
Prev
Cron Triggers
Next
Time and TimeProvider