CronDrive
Guides

Crontab format: the five fields and their special characters

Updated 26 October 2026

In a user’s crontab, the one you edit with crontab -e, each job is a line with a schedule of five fields, separated by spaces, and then the command to run:

# ┌───────── minute (0-59)
# │ ┌─────── hour (0-23)
# │ │ ┌───── day of the month (1-31)
# │ │ │ ┌─── month (1-12)
# │ │ │ │ ┌─ day of the week (0-7, Sunday is 0 or 7)
# │ │ │ │ │
  0 2 * * * /path/to/backup.sh

This line runs backup.sh every day at 02:00: minute 0, hour 2, any day of the month, any month and any day of the week. The hours are in the time zone of the server, which may not be yours (see cron and time zones).

The special characters

  • *, any value. * in the hour field means every hour.
  • , separates a list. 0,30 in the minute field runs at minute 0 and at minute 30.
  • - gives a range. 1-5 in the day of the week runs from Monday to Friday.
  • / gives a step. */15 in the minute field runs at minutes 0, 15, 30 and 45. It also works on a range: 0-30/10 is 0, 10, 20 and 30.
  • Names. The months and the days of the week also accept their first three letters in English, like JAN or MON. Some implementations don’t accept them in ranges or lists, so numbers are the safest choice.

The step counts within its field, from the start of the range, and starts over in the next hour, day or month. 0 */7 * * * runs at 0:00, 7:00, 14:00 and 21:00, and the next day again at 0:00: three hours after the last run, not seven. In the same way, */5 in the day of the month runs on days 1, 6, 11, 16, 21, 26 and 31, and then on day 1 of the next month.

The day of the month and the day of the week

When both days are restricted, cron runs the job when either matches, not when both do. 0 0 13 * 5 runs on every 13th and on every Friday, not only on Friday the 13th. To run on a day of the week only within some days of the month, restrict one of them in the schedule and check the other in the command:

0 0 1-7 * * [ "$(date +\%u)" = 1 ] && /path/to/job.sh

That line runs on the first Monday of the month: every day from the 1st to the 7th, the command checks that it’s Monday (date +%u gives 1 to 7, from Monday). The % is written \% because of what comes next.

The command

  • Cron runs it with /bin/sh, not with your shell, and with a short PATH. Use absolute paths, or set SHELL and PATH at the top of the crontab (see why your cron job isn’t running).
  • % is a new line for cron: what follows the first % goes to the command’s input. Write \% for a % in the command, as in date +\%F.
  • The output goes by email to the crontab’s user, or to the address in MAILTO. If the server doesn’t send email, redirect it to a file: >> /var/log/job.log 2>&1.

The other lines of a crontab

  • Lines that start with # are comments.

  • Variables, like PATH=/usr/local/bin:/usr/bin:/bin, SHELL=/bin/bash or MAILTO=you@example.com, apply to the lines below them. Some implementations, like cronie, also accept CRON_TZ for the time zone of the schedules.

  • In /etc/crontab and /etc/cron.d/, each line has a sixth field, with the user that runs the command, before the command:

    0 2 * * * root /usr/local/bin/backup.sh

The macros

Instead of the five fields, a line can start with one of these:

  • @hourly is 0 * * * *.
  • @daily, or @midnight, is 0 0 * * *.
  • @weekly is 0 0 * * 0, on Sunday.
  • @monthly is 0 0 1 * *.
  • @yearly, or @annually, is 0 0 1 1 *.
  • @reboot runs the command once when cron starts, usually when the server boots.

Examples

These expressions are only the schedule: the command goes after them.

Not crontab: seconds and other formats

Crontab has no field for the seconds, so a line runs at most once a minute (see how to run a cron job every few seconds). Some schedulers use other formats:

  • Spring and Quartz add the seconds as the first field, and Quartz a seventh field with the year. Quartz counts the days of the week from Sunday as 1.
  • AWS, in the rules of EventBridge, writes cron(0 2 * * ? *): the five fields, with a ? in one of the days, and the year at the end. Those rules run in UTC.
  • Kubernetes CronJob and GitHub Actions use the five fields of crontab. GitHub Actions reads them in UTC by default.

The cron tester reads all of them, says what they mean and gives the crontab expression that runs at the same minutes.

Check it before saving

A mistake in the schedule doesn’t show up as an error: the job just runs at another time, or never. Paste the expression in the cron tester to see its next runs in your server’s time zone, and set up an alert for the day the job doesn’t run when it should.

CronDrive emails you, or posts to Slack, when a job with this schedule fails, or doesn't start or finish on time. Free for up to 15 jobs.

What you'd see with this schedule

An example with the last runs of this schedule and made-up results: one failed and one didn't run.

Times in UTC.

Due
Mon 26 Oct, 02:00 On time Started 02:00, finished 02:13, took 13 min.
Sun 25 Oct, 02:00 Didn't run Alerts sent at 02:05 and 02:30.
Sat 24 Oct, 02:00 On time Started 02:00, finished 02:14, took 14 min.
Fri 23 Oct, 02:00 Failed with code 1 Alert sent at 02:04. Started 02:00, finished 02:04, took 4 min.
Thu 22 Oct, 02:00 On time Started 02:00, finished 02:13, took 13 min.
Wed 21 Oct, 02:00 On time Started 02:00, finished 02:14, took 14 min.

The alert of the failed run

Email from CronDrive, Fri 23 Oct, 02:04

Failed (exit code 1): "Your job"

The job "Your job" failed with exit code 1.

If you connect Slack, the same message goes to your channel.

The change in your crontab

0 2 * * * curl -fsS -m 10 https://job.crondrive.com/uG2Exw/start/$$; /path/to/job.sh; curl -fsS -m 10 https://job.crondrive.com/uG2Exw/end/$?/$$

Two calls around your command, in the same line. Your job's line comes with its own token.

Monitor this schedule