Cron expressions explained, with examples and gotchas

A cron expression is five fields that say when to run something. It reads easily once you know the order; what surprises people is a handful of rules, such as what happens when you set both a day of the month and a weekday. The syntax, examples to copy and the usual traps.

Reviewed on 3 October 2026 · 5 min read

The five fields

A standard cron line has five time fields, followed by the command. Per the crontab(5) manual page, the fields and their allowed values are:

PositionFieldAllowed values
1minute0–59
2hour0–23
3day of month1–31
4month1–12 (or names)
5day of week0–7 (0 or 7 is Sunday, or use names)

The command runs when the minute, hour and month fields match the current time, and the day condition is met (more on that below). cron examines its entries every minute, so the smallest unit is one minute: there is no seconds field in this syntax.

The special characters

  • * means "every value" ("first to last").
  • , makes a list: 1,15 is the 1st and the 15th.
  • - makes an inclusive range: 8-11 in the hour field is 8, 9, 10 and 11.
  • / adds a step to a range or to *: */5 is every 5 units, and 0-23/2 in the hour field is every other hour.

Names work for months and days of week (the first three letters, in any case: jan, mon…). The crontab(5) page also allows ranges and lists of names such as mon,wed,fri, but some older implementations do not, so numbers are the safer choice.

Examples you can copy

ExpressionRuns
*/15 * * * *every 15 minutes (at :00, :15, :30, :45)
0 * * * *at the top of every hour
0 9 * * 1-5at 09:00, Monday to Friday
0 9-17 * * *every hour on the hour from 09:00 to 17:00 inclusive
0 */2 * * *every two hours on the hour (00:00, 02:00 … 22:00)
5 4 * * 0at 04:05 every Sunday
0 0 1 * *at midnight on the 1st of every month
0 0 1 1 *at midnight on 1 January

To check what an expression you inherited actually means, paste it into the cron expression explainer: it translates it into plain language and lists the next run times, which is the quickest way to catch an expression that does not do what you thought.

Gotcha 1: day of month and day of week are OR, not AND

This one catches almost everyone. If you restrict both the day-of-month and the day-of-week fields (neither is *), the command runs when either matches. The crontab(5) page gives an example: 30 4 1,15 * 5 runs at 04:30 on the 1st and 15th of each month plus every Friday, not only on Fridays that fall on the 1st or 15th. If you want "the first Friday of the month", cron cannot express it directly: schedule it for every Friday and have the script check that the day is 7 or less.

Gotcha 2: steps restart; they do not "carry over"

*/7 in the minute field means minutes 0, 7, 14 … 56, and then it starts again at 0 in the next hour, so the gap between 56 and 0 is only 4 minutes. A step only gives an even interval when it divides the range exactly: */5, */10, */15 and */30 do for minutes; */7 does not. The manual makes the same point with hours: steps are evaluated just within the field, so */23 in the hour field means hour 0 and hour 23 of each day, not "every 23 hours".

Gotcha 3: "last day of the month" does not exist

Months have 28 to 31 days, and standard cron has no "last day" token. The usual workaround is to run daily (0 0 * * *) and have the command check whether tomorrow is the 1st before doing the work. Also remember that in a crontab, an unescaped % in the command is turned into a newline, so a date +%d inside it has to be written as date +\%d.

Gotcha 4: time zones and daylight saving time

cron uses the system's local time unless told otherwise (some implementations accept a CRON_TZ variable). That matters on the nights the clocks change. The crontab(5) manual says it plainly: non-existent times, such as the "missing hour" during the daylight saving conversion, will never match, so jobs scheduled in that hour are not run, and times that occur more than once will cause matching jobs to run twice. Put important jobs outside the 01:00–03:00 window, or run the machine on UTC. For a rundown of when clocks change, see the guide to clock-change dates, and use the time zone converter to translate a schedule into the server's time.

Gotcha 5: not every scheduler speaks the same dialect

The five-field form above is the classic Unix one. Other systems differ. GitHub Actions uses POSIX cron syntax with five fields, runs scheduled workflows in UTC by default (you can optionally give an IANA time zone), runs them on the latest commit of the default branch, and does not allow a shorter interval than every 5 minutes. Others, such as Quartz-style schedulers, add a seconds field (and sometimes a year), shifting every position by one. Always check which dialect your tool uses before copying an expression from somewhere else.

A short checklist before you ship a schedule

  1. Read it back in words, or use the explainer, and check the next five run times.
  2. If you set both day-of-month and day-of-week, confirm you really want OR.
  3. Avoid * * * * * unless you truly need every minute.
  4. Decide the time zone on purpose, and keep jobs away from the daylight-saving hour.
  5. Make the job safe to run twice, because sooner or later it will.

Sources and further reading

Figures checked on 3 October 2026.

Do it now, free, in your browser. Your files are not uploaded.

Build a cron schedule and see what it means and when it will run next.

Frequently asked questions

What do the five fields of a cron expression mean?
In order: minute (0–59), hour (0–23), day of month (1–31), month (1–12) and day of week (0–7, where 0 and 7 are Sunday).
How do I run a cron job every 5 minutes?
Use */5 * * * *. It runs at minutes 0, 5, 10 … 55 of every hour.
What happens if I set both day of month and day of week?
The job runs when either field matches, not both. For example, 30 4 1,15 * 5 runs on the 1st, the 15th and every Friday.
Does cron run jobs during the daylight saving time change?
Times that do not exist (the skipped hour) never match, so those jobs do not run; times that occur twice make matching jobs run twice. Keep important jobs away from that hour or schedule in UTC.
What time zone does cron use?
The system's local time by default; some implementations accept a CRON_TZ variable. GitHub Actions uses UTC by default.
Can cron run every second?
No. Standard cron has a one-minute resolution and no seconds field.