Skip to main content

← Back to blog

Cron Expressions Explained: The 5 Fields and Common Examples

Cron is how Unix-like systems schedule repeating jobs, and its expression format shows up far beyond crontab — in CI pipelines, Kubernetes CronJobs and cloud schedulers. The syntax looks cryptic at first, but it is just five fields separated by spaces.

What our tool says about the most common schedule. Type 0 9 * * 1-5 into the cron generator and it reads the expression back field by field:

Minute: 0
Hour: 9
Day of month: every
Month: every
Day of week: Mon-Fri

Two things that trip people up are visible here. Day-of-month and day-of-week are both every, and when both are unrestricted the schedule simply runs daily — but restricting both makes them behave as OR, not AND, which is the single most common cron bug. And 1-5 is Monday to Friday because the week starts at 0 = Sunday.

The five fields

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

Each field answers “at which values does this run?” A * means “every”. So * * * * * runs every single minute.

Syntax within a field

  • * — every value.
  • 5 — exactly 5.
  • 1-5 — a range, 1 through 5.
  • */15 — a step: every 15th value (0, 15, 30, 45).
  • 1,15,30 — a list of specific values.
  • Names — JAN–DEC for months, SUN–SAT for weekdays.

Ready-to-use examples

ExpressionMeaning
* * * * *Every minute
*/5 * * * *Every 5 minutes
0 * * * *Every hour, on the hour
0 9 * * *Every day at 09:00
0 9 * * 1-5Weekdays at 09:00
0 0 * * 0Every Sunday at midnight
0 0 1 * *The 1st of every month
30 3 1 1 *03:30 on 1 January

Every reading below came out of our own cron generator — it parses the five fields and says them back in words, which is the fastest way to catch a field you counted wrong.

ExpressionWhat our tool reads it as
* * * * *Minute: every Hour: every Day of month: every Month: every Day of week: every
*/15 * * * *Minute: every 15 Hour: every Day of month: every Month: every Day of week: every
0 * * * *Minute: 0 Hour: every Day of month: every Month: every Day of week: every
0 9 * * 1-5Minute: 0 Hour: 9 Day of month: every Month: every Day of week: Mon-Fri
30 3 * * 0Minute: 30 Hour: 3 Day of month: every Month: every Day of week: Sun
0 0 1 * *Minute: 0 Hour: 0 Day of month: 1 Month: every Day of week: every
0 0 * * 1Minute: 0 Hour: 0 Day of month: every Month: every Day of week: Mon
0 */2 * * *Minute: 0 Hour: every 2 Day of month: every Month: every Day of week: every

The one gotcha: day-of-month vs day-of-week

If both the day-of-month and day-of-week fields are restricted (not *), cron runs when either matches — not both. So 0 0 13 * 5 fires on the 13th and every Friday, not only on Friday the 13th. When in doubt, verify against real run times.

The two expressions that trip everyone up are one character apart. 0 0 1 * * reads as Minute: 0 Hour: 0 Day of month: 1 Month: every Day of week: every — the first day of every month. 0 0 * * 1 reads as Minute: 0 Hour: 0 Day of month: every Month: every Day of week: Mon — every Monday. Field 3 is day-of-month and field 5 is day-of-week; setting both is an OR in most implementations, not an AND, so 0 0 1 * 1 fires on the 1st and every Monday.

Check it before you ship it

The safest way to trust a cron is to see the actual times it will fire. The cron expression generator explains each field in plain language and lists the next run times in your local zone, with one-click presets. It all runs in your browser.

Shortcut strings

Most cron daemons accept named shortcuts in place of the five fields:

ShortcutSame asRuns
@yearly (or @annually)0 0 1 1 *Once a year, 1 Jan
@monthly0 0 1 * *1st of each month
@weekly0 0 * * 0Every Sunday
@daily (or @midnight)0 0 * * *Every day at midnight
@hourly0 * * * *Every hour
@reboot—Once at startup

Also watch for field-count variants: Spring’s @Scheduled, Quartz and some cloud schedulers add a seconds field at the front (six fields), and AWS EventBridge uses a six-field form that forbids setting day-of-month and day-of-week together. A five-field expression dropped into a six-field parser is off by one field.

Time zones and daylight saving

Classic crontab has no time-zone field — it fires in the daemon’s local time. On Linux you can override that per file with a CRON_TZ=UTC line (or TZ); most cloud schedulers show a time-zone dropdown instead. For anything shared across regions, UTC is the safe default so nobody has to reason about offsets.

Daylight-saving switches are the classic trap. When clocks spring forward, a job set inside the skipped hour (say 30 2 * * *) may not run that day; when they fall back, a job in the repeated hour can run twice. Keep critical jobs outside the 01:00–03:00 window, or run them in UTC. If you also deal with epoch times, the complete guide to Unix timestamps covers how those map to wall-clock time.

Quick FAQ

  • Can I combine ranges and steps? Yes — 0-30/10 means 0, 10, 20, 30.
  • What does */2 mean in the hour field? Every second hour: 0, 2, 4 … 22.
  • Does cron catch up on missed runs? No. If the machine is off at the scheduled time, plain cron skips it — use anacron when catch-up matters.