Cron Expression Generator

Build crontab schedules from presets or the five cron fields and copy the expression.

Cron Expression Generator: Build, Explain and Test Crontab Schedules

Pick a preset or fill in the five fields above, and the generator assembles the cron expression, explains it in plain English and lists the next five times it will run in your local time. It also works the other way: paste an expression from a crontab, a Kubernetes CronJob or a CI file into the expression box to see what it really means. Invalid values, such as minute 60 or a backwards range, are reported with the field that is wrong.

The five crontab fields

A standard cron expression has five fields separated by spaces, followed in a crontab by the command to run:

┌──────── minute        0-59
│ ┌────── hour          0-23
│ │ ┌──── day of month  1-31
│ │ │ ┌── month         1-12 or jan-dec
│ │ │ │ ┌ day of week   0-7 or sun-sat (0 and 7 are Sunday)
│ │ │ │ │
* * * * *  /path/to/command

Each field accepts * for every value, a single number, a list such as 1,15, a range such as 9-17, and a step such as */15 or 0-30/10. Month and weekday names work in lists and ranges: mon-fri, jan,jul. The generator accepts all of these and shows what each field expands to in the description.

Common cron schedules

* * * * *        every minute
*/5 * * * *      every 5 minutes
*/15 * * * *     every 15 minutes
0 * * * *        every hour, on the hour
0 */2 * * *      every 2 hours
0 9 * * *        every day at 09:00
0 9 * * 1-5      weekdays at 09:00
30 2 * * 0       Sundays at 02:30
0 0 1 * *        midnight on the 1st of every month
0 0 1 1 *        once a year, 1 January

The next-run list is the quickest way to catch a step that does not do what you expect. Steps are counted from the start of the field's range, so */5 lands on minutes 0, 5 … 55. Enter */7 and the list shows :49, :56 and then :00, a four-minute gap at the top of every hour. Cron cannot express a true every-seven-minutes interval; that needs a scheduler with interval support.

Many cron implementations also accept shortcuts: @hourly, @daily (or @midnight), @weekly, @monthly, @yearly (or @annually) and @reboot. Paste one into the generator to see the equivalent five fields; @reboot has no schedule, it runs once when the cron daemon starts.

The day-of-month and day-of-week trap

When both day fields are restricted, cron runs the job on days that match either field, not only days that match both. 0 9 1 * 1 does not mean "09:00 on the 1st if it is a Monday"; it means 09:00 on the 1st of every month and also every Monday. The crontab manual states the rule explicitly, and the generator warns you when both fields are set.

Cron has no syntax for "the first Monday of the month". The usual workaround keeps the day of month at 1-7, leaves the day of week as *, and tests the weekday inside the command: 0 9 1-7 * * [ "$(date +\%u)" = 1 ] && /path/to/job. The backslash before % is required, as explained below.

Why a cron job does not run

Most cron problems are about the environment, not the expression. Cron runs commands with /bin/sh and a minimal environment: PATH is short, your shell profile is not loaded, and the working directory is the user's home. A script that works in your terminal can fail under cron because node, php or python3 is not on that PATH. Use absolute paths, or set PATH at the top of the crontab.

The % character is special in a crontab: unescaped, it becomes a newline and everything after it is passed to the command as standard input. That silently breaks date +%Y-%m-%d; write date +\%Y-\%m-\%d instead.

Redirect output so failures are visible: */5 * * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1. Without it, output is mailed to the user if mail is configured and otherwise lost.

crontab -e          # edit your crontab
crontab -l          # list it
grep CRON /var/log/syslog        # Debian/Ubuntu: did cron start the job?
journalctl -u cron               # systemd systems (the unit is crond on RHEL)

Time zones

Cron uses the server's time zone. A job scheduled for 09:00 on a server in UTC runs at 09:00 UTC, whatever your laptop says. The next-run list in the generator uses your browser's time zone, so compare it with the server's: run date or timedatectl there. Some implementations, including cronie, support a CRON_TZ variable to set a time zone for the table.

Daylight-saving changes affect jobs scheduled in the skipped or repeated hour, usually between 01:00 and 03:00 local time. A job at 02:30 may run twice or not at all on those nights, depending on the implementation. Schedule important jobs outside that window, or run the server in UTC.

Cron syntax in other tools

Kubernetes CronJobs and GitHub Actions use the same five fields. GitHub Actions schedules always run in UTC and cannot run more often than every five minutes. Kubernetes interprets the schedule in the controller's time zone unless you set spec.timeZone.

Other schedulers add fields. Spring's @Scheduled(cron = …) and Quartz put a seconds field first, and AWS EventBridge has six fields ending with the year and requires ? in one of the two day fields. The generator works with the classic five fields, so drop the seconds or the year before pasting such an expression, and add it back when you copy the result into the other system.

Frequently asked questions

What is the cron expression for every 5 minutes?

*/5 * * * * runs at minutes 0, 5, 10 and so on of every hour. Use */10 for every 10 minutes and */15 for every 15 minutes.

What do the five fields of a cron expression mean?

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). An asterisk means every value.

How do I run a cron job on weekdays only?

Put 1-5 in the day-of-week field, for example 0 9 * * 1-5 for 09:00 Monday to Friday. Leave the day-of-month field as *.

Why does my cron job run on the wrong days?

If both day of month and day of week are restricted, cron runs on days matching either one. 0 9 1 * 1 runs on the 1st and on every Monday.

Why does my cron job not run?

Common causes are a minimal PATH, relative paths in the script, an unescaped % in the command, and a server time zone different from yours. Redirect output to a log file with >> file.log 2>&1 to see the error.

What time zone does cron use?

The time zone of the server running the cron daemon. GitHub Actions uses UTC, and Kubernetes uses the controller's time zone unless spec.timeZone is set.