Quartz.NET Cron Expressions: Complete Guide with Examples
Quartz.NET Cron Expressions: Complete Guide with Examples
If you’ve been using Quartz.NET for background job scheduling, you’ve likely encountered the power and flexibility of cron expressions. They let you describe when a job should run using a compact, human‑readable syntax. Whether you’re new to cron or looking to deepen your understanding, this guide covers everything you need—syntax breakdown, over 20 practical examples, common pitfalls, how to test cron expressions, and a quick comparison with the SimpleTrigger.
Author: QuartzNetPro Team
Published: Wednesday, November 19, 2025
Why Cron Expressions Matter in Quartz.NET
Cron expressions are the backbone of scheduled workflows that need fine‑grained time control—think daily reports, maintenance tasks, or event‑driven triggers. In Quartz.NET, a CronScheduleBuilder turns a string like "0 0 * * * ?" into a trigger that fires at the top of every hour. Mastering cron syntax saves time, reduces errors, and ensures your application behaves exactly as intended.
1. Cron Syntax Explained
A Quartz.NET cron expression consists of six mandatory fields followed by an optional seventh:
| Position | Field | Allowed Values | Description |
|---|---|---|---|
| 1 | Seconds | 0-59 |
Seconds within the minute |
| 2 | Minutes | 0-59 |
Minutes within the hour |
| 3 | Hours | 0-23 |
Hours within the day |
| 4 | Day of Month | 1-31 |
Day of the month |
| 5 | Month | 1-12 or JAN-DEC |
Month of the year |
| 6 | Day of Week | 1-7 or SUN-SAT |
Day of the week (1=SUN, 7=SAT) |
| 7 | Year (optional) | 1970-2099 |
Specific year |
Special characters
*– all values?– no specific value (used only in Day of Month or Day of Week)-– range (e.g.,1-5),– list (e.g.,MON,WED,FRI)/– increment (e.g.,*/15means every 15 units)L– last (e.g.,Lin day‑of‑month means last day)W– weekday (e.g.,15Wis the nearest weekday to the 15th)#– nth day of the week (e.g.,3#2is the second Wednesday)
Important: Either Day of Month or Day of Week must be ? (not both can be specific values).
2. 20+ Practical Cron Trigger Examples
Below is a cheat‑sheet of real‑world cron expressions. Use them as a starting point or adapt them for your own schedules.
| # | Expression | When It Fires | Use Case |
|---|---|---|---|
| 1 | 0 0/5 * * * ? |
Every 5 minutes | High‑frequency polling |
| 2 | 0 0/15 * * * ? |
Every 15 minutes | Periodic cache refresh |
| 3 | 0 0/30 * * * ? |
Every 30 minutes | Data aggregation |
| 4 | 0 0 0/1 * * ? |
Every hour | Hourly maintenance |
| 5 | 0 0 0 1/1 * ? |
Daily at midnight | Daily reports |
| 6 | 0 0 8 1/1 * ? |
Daily at 08:00 | Morning batch job |
| 7 | 0 0 17 * * ? |
Daily at 17:00 | Evening cleanup |
| 8 | 0 30 7 ? * MON-FRI |
Weekdays at 07:30 | Morning startup tasks |
| 9 | 0 0 12 ? * SUN |
Every Sunday at noon | Weekly status report |
| 10 | 0 0 12 * * ? |
Daily at noon | Lunch‑break reminder |
| 11 | 0 0 9-17 ? * MON-FRI |
Every hour 9am-5pm weekdays | Real‑time monitoring |
| 12 | 0 0 0 1 * ? |
First day of month at midnight | Monthly invoicing |
| 13 | 0 0 0 L * ? |
Last day of month at midnight | Month‑end batch |
| 14 | 0 0 0 ? * MON |
Every Monday at midnight | Weekly backups |
| 15 | 0 0 0/6 ? * * |
Every 6 hours | Periodic health checks |
| 16 | 0 0 0-23/2 ? * * |
Every 2 hours | Data sync |
| 17 | 0 0 12 15 * ? |
15th of each month at noon | Mid‑month report |
| 18 | 0 0 8-17 * * ? |
Hourly from 8am-5pm daily | Business‑hours batch |
| 19 | 0 0 6-22/3 * * ? |
Every 3 hours from 6am to 10pm | Peak‑time processing |
| 20 | 0 0 0 ? * MON-FRI |
Every weekday at midnight | Weekday overnight jobs |
| 21 | 0 0 0 ? * * 2026 |
Every day at midnight in 2026 | Year-specific processing |
| 22 | 0 0 12 1 1 ? |
January 1st at noon | New Year kickoff |
Tip: Always test your expressions before deploying to production.
3. Common Mistakes and How to Avoid Them
| Mistake | Why It Happens | Fix |
|---|---|---|
Using * in both Day‑of‑Month and Day‑of‑Week |
Quartz requires one to be ? |
Replace one field with ? |
| Specifying both day fields | Cannot use both simultaneously | One must be ? |
Misunderstanding L and W |
They’re only for day‑of‑month | Use L for last day, W for nearest weekday |
| Forgetting the seconds field | Quartz.NET requires all 6 fields | Always include seconds (use 0 if not needed) |
| Mixing “/” and “-” incorrectly | Conflicts in ranges | Keep ranges separate from increments |
Using - without proper start < end |
Invalid range | Ensure start <= end |
| Mis‑typed month abbreviations | Quartz is case‑sensitive | Use upper‑case JAN–DEC |
Using ? in non‑day fields |
Only valid for day fields | Use * for other fields |
| Incorrect day-of-week numbering | Confusion about 0 vs 1 for Sunday | Use 1=SUN through 7=SAT or names |
4. Testing Cron Expressions
Quartz.NET ships with a lightweight CronExpression parser. The easiest way to verify a schedule is by using the Cron Expression Tester on our website or via the sample code below:
using Quartz;
using Quartz.Impl;
using System;
var scheduler = await StdSchedulerFactory.GetDefaultScheduler();
var expr = "0 0 12 1/1 * ?";
var cronTrigger = TriggerBuilder.Create()
.WithCronSchedule(expr)
.Build();
Console.WriteLine($"Cron: {expr}");
Console.WriteLine($"Next Fire: {cronTrigger.GetFireTimeAfter(DateTimeOffset.UtcNow)}");
Running this snippet in a console app prints the next fire time, helping you confirm the schedule matches your expectations.
For more complex testing, try our Cron Expression Tester widget where you can paste an expression and see a visual timeline.
5. Cron vs SimpleTrigger
-
CronTrigger
- Supports complex schedules via 6/7 fields.
- Good for recurring patterns (e.g., “every Tuesday at 14:30”).
- Requires correct syntax; a single typo can cause job misfires.
-
SimpleTrigger
- Uses
RepeatCountandRepeatInterval. - Ideal for fixed‑interval jobs like “run every 5 minutes”.
- Simpler to configure programmatically.
- Uses
When to choose which?
If your schedule is time‑based (fixed times, days, or months), useCronTrigger.
For interval‑based tasks that just need to fire after a certain duration, useSimpleTrigger.
Example of a SimpleTrigger that fires every 5 minutes:
var simpleTrigger = TriggerBuilder.Create()
.WithSimpleSchedule(x => x
.WithIntervalInMinutes(5)
.RepeatForever())
.Build();
6. Using Cron Expressions in Production with QuartzNetPro
When you need enterprise‑grade reliability, our QuartzNetPro module adds:
- Misfire handling policies to avoid job loss.
- Time‑zone awareness so jobs respect local time even in distributed clusters.
- Optimized job stores for high‑volume cron jobs without heap bloat.
var trigger = TriggerBuilder.Create()
.WithIdentity("myTrigger")
.WithCronSchedule("0 0 12 * * ?", x => x
.InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time")))
.Build();
This configuration guarantees your job fires at noon PST every day, regardless of daylight savings shifts.
Takeaway
- Master the six mandatory fields and the optional year field.
- Use our cheat‑sheet as a starting point for any recurring schedule.
- Double‑check common pitfalls before deploying.
- Test expressions with the built‑in parser or our online widget.
- Choose
CronTriggerfor complex, time‑specific schedules; chooseSimpleTriggerfor simple intervals.