1. Home
  2. Guides
  3. Cron Expressions: A Cheat Sheet and Its Traps

Cron expressions, and the two rules that catch everybody

Five fields of stars and numbers look like a puzzle. Once you know that day-of-month and day-of-week are combined with OR rather than AND, and that the expression is evaluated in the scheduler timezone, most cron confusion disappears.

By Enrique M. · 7 min read · Last reviewed 2026-10-09

The five fields

A standard Unix cron expression is five whitespace-separated fields, read left to right: minute, hour, day of month, month and day of week. Each field accepts a list of alternatives separated by commas, ranges with a hyphen, steps with a slash and an asterisk meaning every value.

  • `minute` — 0 to 59
  • `hour` — 0 to 23
  • `day of month` — 1 to 31
  • `month` — 1 to 12, or JAN to DEC
  • `day of week` — 0 to 6, or SUN to SAT, with 7 also meaning Sunday

The OR rule

When you restrict both the day-of-month field and the day-of-week field, standard cron fires the job whenever either of them matches. It does not wait for both.

So `0 0 13 * 5` means "the 13th of the month, and every Friday", not "the 13th of the month when it is a Friday". If you want the intersection, you need a scheduler that supports it, or you express the job in a different way.

# Every day at 03:30
30 3 * * *

# Every Monday at 09:00
0 9 * * 1

# Every 15 minutes
*/15 * * * *

# Every 15 minutes between 09:00 and 18:00 on weekdays
*/15 9-18 * * 1-5

The timezone rule

A cron expression carries no timezone. It is evaluated in whatever timezone the scheduler runs in, which on a Linux server is usually UTC and in a container is whatever the image says.

This is the single most common cause of a job that "runs at the wrong time". The cron entry is not wrong; the assumption about the timezone is. Setting the timezone explicitly in the scheduler configuration, or in the crontab itself with `CRON_TZ`, removes the ambiguity.

The same schedule in other schedulers

Quartz has seven fields, adding seconds and a year, and uses a question mark in place of a field that does not apply. AWS EventBridge and GitHub Actions each have their own dialect, and GitHub Actions runs on UTC by default.

  • Unix cron: `0 9 * * 1`
  • Quartz: `0 0 9 ? * MON`
  • AWS EventBridge: `cron(0 9 ? * MON-FRI *)`
  • GitHub Actions: `cron: "0 9 * * 1"` in UTC

What to take away

  • Day-of-month and day-of-week are combined with OR, not AND.
  • The expression is evaluated in the scheduler timezone, which is often UTC.
  • Quartz has seven fields, AWS and GitHub have their own dialects.
  • A schedule of `*/5 * * * *` is 288 executions a day — check that you meant it.

Related tools