← Back to Blog

Cron Expression Guide: Write Schedules with Confidence

Cron expressions power scheduled tasks in Linux, CI/CD pipelines, cloud functions, and job schedulers. Learn the syntax once and you will never need to look it up again.

Pankaj Kumar
Senior Software Engineer — .NET, Blazor, ASP.NET Core
4+ years building production .NET and Blazor applications. Every DevToolsHub tool and article comes from real daily development work — not documentation summaries.
Published 19 May 2026· Last reviewed Jun 2026· 6 min read · About the author →
Configured scheduled tasks across Linux servers, AWS CloudWatch Events, Azure Logic Apps, and Kubernetes CronJobs. A timezone-related incident involving a batch job that ran 5.5 hours early is the reason this article leads with UTC.
Key takeaways
  • The 5-field cron structure — minute, hour, day-of-month, month, day-of-week — and what each field controls
  • Special characters: *, commas, hyphens, and slashes — with real examples of each combination
  • Why the same cron string means different things in 5-field POSIX versus 6-field Quartz format
  • The timezone, day-of-week, and missed-run pitfalls that cause unexpected behaviour in production
Table of Contents

What is cron?

Cron is a time-based job scheduler in Unix-like operating systems. The name comes from the Greek word for time, chronos. It runs background tasks (called cron jobs) at specified intervals — anything from "every minute" to "on the first Monday of every quarter at 3 AM". Cron syntax is also used in GitHub Actions, AWS CloudWatch Events, Azure Logic Apps, Kubernetes CronJobs, and many application-level schedulers like Quartz (.NET/Java) and node-cron.

The 5-field cron format

A standard cron expression has five fields separated by spaces:

┌──────────── minute (0–59)
│  ┌─────────── hour (0–23)
│  │  ┌──────── day of month (1–31)
│  │  │  ┌───── month (1–12)
│  │  │  │  ┌── day of week (0–7, 0 and 7 both mean Sunday)
│  │  │  │  │
*  *  *  *  *

Special characters

  • * (asterisk) — matches every possible value in that field. * in the hour field means "every hour".
  • , (comma) — lists multiple values. 1,3,5 in the day-of-week field means Monday, Wednesday, Friday.
  • - (hyphen) — defines a range. 9-17 in the hour field means hours 9 through 17 inclusive.
  • / (slash) — specifies a step. */5 in the minute field means "every 5 minutes". 0/15 means "at 0, 15, 30, 45".

Practical examples

Expression Meaning
* * * * * Every minute
0 * * * * Every hour at minute 0
0 0 * * * Every day at midnight
0 9 * * 1-5 Weekdays at 9:00 AM
*/15 * * * * Every 15 minutes
0 0 1 * * First day of every month at midnight
0 0 * * 0 Every Sunday at midnight
30 8 * * 1 Every Monday at 8:30 AM
0 0 1 1 * Once a year, 1 Jan at midnight
0 9,17 * * 1-5 Weekdays at 9 AM and 5 PM

The 6-field format (with seconds)

Some schedulers — notably Quartz (.NET and Java), Spring Scheduler, and some cloud platforms — add a seconds field at the beginning, making it a 6-field expression:

┌──────────── second (0–59)
│  ┌─────────── minute (0–59)
│  │  ┌──────── hour (0–23)
│  │  │  ┌───── day of month
│  │  │  │  ┌── month
│  │  │  │  │  ┌─ day of week
│  │  │  │  │  │
0  *  *  *  *  *

This is a common source of confusion: the same string 0 * * * * means "every hour at minute 0" in 5-field cron, but means "at second 0 of every minute, every hour" in 6-field Quartz format. Always check which format your scheduler expects.

Common pitfalls

  • Timezone confusion — cron runs in the server's local timezone by default. If your server is in UTC and your users are in IST (UTC+5:30), a job scheduled at 0 2 * * * runs at 7:30 AM IST, not 2:00 AM. Use a timezone-aware scheduler or specify the timezone explicitly.
  • Day-of-month AND day-of-week interaction — in most cron implementations, if both day-of-month and day-of-week are specified (not *), the job runs when either condition is met, not when both are. This surprises many developers.
  • Minute-level granularity — standard 5-field cron cannot schedule tasks more frequently than once per minute. For sub-minute jobs, use your language's task runner or a dedicated scheduler.
  • Missed runs — if the cron daemon was not running when a job was due (server was down), most implementations simply skip that run. Use a scheduler with catch-up logic if missed runs must execute.
Try the free tool
Cron Expression Generator

Generate cron expressions visually and get a plain-English description of any schedule — no syntax memorisation required.

Open Cron Expression Generator