Cron Expression Syntax Guide

Cron is the Unix scheduling language β€” five fields, a handful of special characters, and you can describe almost any repeating schedule. Here's everything you need to know.

What is cron?

Cron is a time-based job scheduler built into Unix and Linux systems. The name comes from Chronos, the Greek god of time. It has been part of Unix since the 1970s and is still the most widely used way to run recurring tasks on servers today.

You tell cron when to run a command by writing a cron expression β€” a compact, five-field string like 0 9 * * 1-5. Every minute, the cron daemon wakes up, reads your crontab file, and fires any job whose expression matches the current time.

Cron is popular for one simple reason: it works everywhere. Any Linux server, any container, any cloud VM β€” they all support the same syntax. Tools like GitHub Actions, AWS EventBridge, Kubernetes CronJobs, Heroku Scheduler, and Railway all speak cron. Learn it once; use it for your entire career.

The 5 fields

A cron expression is five space-separated fields. Reading left to right:

* * * * *
MIN (0–59)HOUR (0–23)DOM (1–31)MON (1–12)DOW (0–6)
#FieldAllowed range
1MinuteMIN0–59
2HourHOUR0–23
3Day of monthDOM1–31
4MonthMON1–12
5Day of weekDOW0–6 (Sun=0)

DOW: 0 = Sunday, 1 = Monday, … 6 = Saturday. Some systems also accept 7 for Sunday. Month names (JAN–DEC) and day abbreviations (MON–SUN) work in most implementations.

Special characters

*
Wildcard

Every possible value.

* in HOUR→Every hour
,
List

Multiple specific values.

1,15 in DOM→1st and 15th of the month
-
Range

A contiguous span of values.

9-17 in HOUR→Every hour from 9 AM to 5 PM
*/n
Step

Every nth value starting from the beginning.

*/15 in MIN→Every 15 minutes (0, 15, 30, 45)
n/s
Offset step

Every sth value starting at n.

5/15 in MIN→Minutes 5, 20, 35, 50

10 common patterns

Copy any of these into CronScope to see exactly when they fire.

0 9 * * 1-5Weekday morning

At 9:00 AM, Monday through Friday. The workhorse of scheduled jobs β€” daily digests, report emails, standup reminders.

0 0 1 * *First of the month

At midnight on the 1st of every month. Ideal for monthly billing runs, archive rotations, and summary reports.

0 * * * *Every hour

At minute 0 of every hour. Good for cache-warming, health pings, and lightweight sync jobs.

*/5 * * * *Every 5 minutes

288 runs per day. Use only when near-real-time polling is genuinely required β€” queue workers, webhook retries.

0 0 * * 0Every Sunday midnight

Weekly maintenance window. Database vacuums, dependency audits, weekly digest emails.

30 6 * * 1-5Weekday 6:30 AM

Before-business-hours processing. Data imports, overnight batch results, pre-cache warming before users arrive.

0 0 * * *Every midnight

Daily cleanup at midnight UTC. Log rotation, temp-file pruning, daily snapshot triggers.

0 12 * * *Every noon

Midday jobs. Useful for tasks that should run outside peak morning hours but still within business hours.

0 0 1 1 *Once a year (Jan 1)

Annual jobs: year-end archive, subscription renewal notices, anniversary emails. Fires exactly once per year.

0 9-17 * * 1-5Every hour, business hours

At minute 0, every hour from 9 AM to 5 PM, weekdays only. 9 runs/day β€” good for throttled polling during office hours.

Common mistakes

Forgetting that * * * * * means 1,440 runs/day

Every field set to * means β€œevery minute” β€” that's 60 Γ— 24 = 1,440 executions per day. If you want every hour, use 0 * * * * (at minute 0 of every hour).

Thinking in local time when your server runs UTC

A cron expression has no timezone β€” it fires based on the system clock. If your server is UTC+0 and you write 0 9 * * *, it fires at 9 AM UTC, not 9 AM in your local timezone. Use CronScope's timezone selector to verify the actual local time. Full timezone guide β†’

DOM + DOW interact with OR logic

When you set both β€œday of month” and β€œday of week” to non-* values, most cron implementations fire if either condition is true (OR), not AND. For example, 0 0 1 * 1 fires on the 1st of the month and also every Monday.

Try any of these expressions in CronScope β€” see them on a 12-month calendar instantly.

Open CronScope ⏱