How-to GuidePublished 10 min read

How to Write crontab, with a Cheat Sheet: The Five Fields, Symbols, Common Examples and Commands

Recurring jobs like “back up every day at 3:00” or “run a monitoring script every 5 minutes” take a single line in crontab on Linux. But the five fields (minute, hour, day of month, month, day of week) and the symbols * , - / are easy to misread at first, and accidents are common: a job that runs 60 times an hour, or one meant to run every 7 minutes that ends up with a 4-minute gap. This article walks through the basics of crontab syntax and what each symbol means, a cheat sheet you can copy from, how to use crontab -e, -l and -r, and what to watch out for when writing the command part, mostly through examples.

A crontab line is “five fields plus a command”

crontab is the configuration file that tells a program called cron when to run what. Each line is one scheduled job: five time values separated by spaces at the start, followed by the command you want to run.

PositionFieldAllowed valuesExample
1stMinute0–5930 → minute 30
2ndHour0–23 (24-hour clock)9 → 9 a.m., 21 → 9 p.m.
3rdDay of month1–311 → the 1st
4thMonth1–12 (JAN–DEC also allowed)4 → April
5thDay of week0–7 (0 and 7 are Sunday; SUN–SAT also allowed)1 → Monday, 5 → Friday

For example, “30 3 * * * /home/user/backup.sh” means “minute 30, hour 3, any day of month, any month, any day of week”, so backup.sh runs at 3:30 every day. The fields go from smaller units to larger ones, except that the day of week comes last. Swapping hour and minute (writing “9 30” for 9:30) is a very common mistake: that reads as “minute 9 of hour 30”, and since 30 isn’t allowed in the hour field, it’s an error.

Symbols: learn * , - / and you can read most expressions

Besides numbers, cron expressions use four symbols. They mean the same thing in every field, so once you know these four you can read almost any expression.

SymbolMeaningExampleHow to read the example
*Every value (no restriction on this field)0 9 * * *Every day at 9:00
,A list of values0 9,18 * * *Every day at 9:00 and 18:00
-A range (from … to …)0 9 * * 1-59:00 Monday to Friday
/A step (every n)*/15 * * * *Minutes 0, 15, 30 and 45 of every hour
- and / togetherA step within a range0 9-17/2 * * *On the hour at 9, 11, 13, 15 and 17
, and - togetherSeveral ranges0 9 * * 1-3,59:00 on Mon, Tue, Wed and Fri

/ means “count in steps of n from the first value in the field”. “*/15” starts at 0 and steps by 15, giving minutes 0, 15, 30 and 45; “5-59/15” gives 5, 20, 35 and 50. It isn’t a timer that fires 15 minutes after the last run; it simply means “run at those minute values”. Keeping that in mind will help you avoid the pitfall in the next section but one.

There are also shorthand forms you can use instead of the five fields: @daily (every day at 0:00), @hourly (minute 0 of every hour), @weekly (Sunday 0:00), @monthly (the 1st at 0:00), @yearly (January 1 at 0:00) and @reboot (once at startup). They’re easy to read, but the time is fixed at 0:00, so watch out for them colliding with other midnight jobs.

A crontab cheat sheet you can copy

Here are frequently used schedules. Times are in the server’s time zone. The command part is left out, so add the command you want to run after the expression.

What you wantCron expressionNotes
Every minute* * * * *Runs 1,440 times a day
Every 5 minutes*/5 * * * *Minutes 0, 5, 10…55 of every hour
Every 10 minutes*/10 * * * *Minutes 0, 10, 20…50 of every hour
Every 30 minutes*/30 * * * *Minutes 0 and 30 of every hour
Every hour (on the hour)0 * * * *Same as @hourly
Every 2 hours0 */2 * * *0, 2, 4…22 o’clock
Every 6 hours0 */6 * * *0, 6, 12 and 18 o’clock
Every day at 0:000 0 * * *Same as @daily
Every day at 3:30 (nightly batch)30 3 * * *Avoiding exactly midnight means less congestion
Every day at 9:00 and 18:000 9,18 * * *Times with the same minute can be combined
Weekdays (Mon–Fri) at 9:000 9 * * 1-5
Every 30 minutes, 9:00–18:59 on weekdays*/30 9-18 * * 1-518:30 runs too
Weekends at 10:000 10 * * 0,6Sunday can be 0 or 7
Every Monday at 9:000 9 * * 1
Every Friday at 17:3030 17 * * 5
The 1st of every month at 0:000 0 1 * *Same as @monthly
The 1st and 15th of every month at 9:000 9 1,15 * *
First day of each quarter (Jan, Apr, Jul, Oct 1)0 0 1 */3 *
January 1 every year at 0:000 0 1 1 *Same as @yearly
Once at startup@rebootcrontab (Linux) only

Some schedules, such as “the last day of every month”, “the second Tuesday of every month” or “the last Friday”, can’t be written exactly with crontab’s five fields alone. They need the command to check the date, which is covered in detail in cron’s day-of-month/weekday OR rule and how to write nth weekdays and month-end.

*/7 isn’t every 7 minutes: the step-value pitfall

“*/n” means “count from 0 in steps of n and stop when you pass the field’s maximum”. In the minute field it counts within 0–59, so if n doesn’t divide 60 evenly, the interval breaks at minute 0 of each hour.

ExpressionWhen it actually runsWhere the gap breaks
*/7 * * * *Minutes 0, 7, 14, 21, 28, 35, 42, 49 and 56 of every hourMinute 56 → next minute 0 is a 4-minute gap
*/25 * * * *Minutes 0, 25 and 50 of every hourMinute 50 → next minute 0 is a 10-minute gap
*/45 * * * *Minutes 0 and 45 of every hourMinute 45 → next minute 0 is a 15-minute gap
0 */5 * * *0, 5, 10, 15 and 20 o’clock20:00 → 0:00 the next day is a 4-hour gap
0 */7 * * *0, 7, 14 and 21 o’clock21:00 → 0:00 the next day is a 3-hour gap

Numbers that divide 60 or 24 evenly keep the interval regular: 1, 2, 3, 4, 5, 6, 10, 12, 15, 20 and 30 for minutes, and 1, 2, 3, 4, 6, 8 and 12 for hours. If you really need an even interval with any other number, run cron every minute or every hour and have the script check how much time has passed since the last run before deciding whether to do the work.

Using crontab -e, -l and -r, and how not to wipe your settings

You don’t open the crontab file directly; you edit it with the crontab command. Each user has their own crontab, and the command acts on the crontab of whoever runs it.

  1. 1

    Check the current settings with crontab -l

    It prints every registered line. If nothing is registered you’ll see “no crontab for username”. Before editing, it’s wise to take a backup with crontab -l > ~/crontab.bak.

  2. 2

    Edit with crontab -e

    An editor opens; write one job per line, then save and quit. Changes take effect as soon as you save, with no need to restart cron. If the syntax is wrong, you’ll get an error on saving and be asked whether to edit again.

  3. 3

    End the last line with a newline

    Some cron implementations ignore the last line if it has no trailing newline. Make a habit of pressing Enter after the final line before saving.

  4. 4

    Use sudo crontab -u for root or other users

    Specify the target user with -u, as in sudo crontab -u www-data -l. Which user you register a job under affects file permissions and the environment variables available.

Note that /etc/crontab and files under /etc/cron.d/ use a slightly different format: there’s an extra “user to run as” field between the five time fields and the command (e.g. 30 3 * * * root /usr/local/bin/backup.sh). If you copy a line in user-crontab format, the command name is read as the user name and nothing runs.

Four things to watch when writing the command

Even with all five time fields correct, the way the command is written often leads to “it works when I run it by hand but not from cron”. That’s because cron runs commands in a minimal environment, different from the one you get when you log in.

  • Use absolute paths for commands and files. cron’s PATH is roughly just /usr/bin:/bin, so commands in places like /usr/local/bin won’t be found
  • Escape %. In a crontab command, % is treated as a newline, so date +%Y%m%d must be written date +\%Y\%m\%d
  • Keep the output in a log. Appending “>> /var/log/backup.log 2>&1” records output, including errors, by adding to the file
  • The shell is /bin/sh. If you use bash-only syntax ([[ ]], arrays and so on), put it in a bash script that starts with #!/bin/bash

Putting this together, a job that “writes a report to a dated file name at 9:00 on weekdays” looks like “0 9 * * 1-5 /usr/local/bin/report.sh > /home/user/report-$(date +\%Y\%m\%d).txt 2>&1”. If it still won’t run, the checklist for when cron isn’t running goes through how to investigate, step by step.

The easiest way to check an expression does what you mean is to paste the crontab line straight into the cron expression checker. It translates it into plain language such as “weekdays (Mon–Fri) at 9:00” and lists the next 10 run times, so mix-ups in the weekday or time stand out immediately. It also warns you if you forgot to escape % in the command.

FAQ

How do I run something every 5 minutes in crontab?
Write “*/5 * * * * command”. It runs at minutes 0, 5, 10…55 of every hour: 12 times an hour, 288 times a day. To limit it to 9:00–18:59 on weekdays, narrow the hour and weekday fields, as in “*/5 9-18 * * 1-5”.
Which number is Monday in the crontab weekday field?
0 is Sunday, 1 is Monday, 2 is Tuesday…6 is Saturday, and 7 is also treated as Sunday. Weekdays (Mon–Fri) are 1-5 and weekends are 0,6. You can also use three-letter English names such as MON or FRI. Note that AWS EventBridge is off by one, with 1 as Sunday.
Do I need to restart cron after editing crontab?
If you edit with crontab -e, changes apply automatically when you save, so no restart is needed. If you change the server’s time zone, cron may keep running on the old time zone, so restart the cron (or crond) service.
Can I recover settings deleted with crontab -r?
crontab -r deletes the settings without confirmation, and there’s no undo. If you have a backup (a file with saved crontab -l output), you can restore it with crontab filename. Without a backup, you’ll have to rewrite it using the execution history in cron’s logs (syslog and so on) as clues to which commands ran when.
Why doesn’t “*/7” run every 7 minutes?
*/7 means “count from minute 0 in steps of 7 up to 59”, so it runs at minutes 0, 7, 14…56. After 56 comes minute 0 of the next hour, not 63, so that one gap is only 4 minutes. Using a number that divides 60 evenly, such as 5, 10, 15, 20 or 30, keeps the interval even.

Tools in this article

Related articles

How-to Guide10 min read

Running GitHub Actions cron on Japan Time: UTC Conversion Table and Fixing Day Shifts and Delays

You wrote “0 9 * * 1-5” in your GitHub Actions schedule, but the workflow ran at 6 p.m. Japan time. That isn’t a typo: GitHub Actions always reads cron expressions in UTC (Coordinated Universal Time). This article covers how to convert a Japan Standard Time (JST) schedule into a UTC cron expression, with a ready-made table; why times between midnight and 8:59 a.m. shift the weekday and date back by one; how to split a schedule into two lines when one won’t do; and what to do when a schedule runs late or not at all.

Read article →
How It Works10 min read

cron’s Day-of-Month and Day-of-Week Are ORed: Writing Second Mondays, Month-End, Last Fridays and Every Other Week Correctly

You wrote “0 9 1-7 * 1” for “9:00 on the first Monday of every month”, and it ran every Monday plus every day from the 1st to the 7th. This very common cron mistake comes from a rule unique to cron: if you specify both the day of month and the day of week, the job runs on days that match either one. This article explains how the OR works and its exception, how to make crontab handle nth weekdays, month-end, last Fridays and every other week correctly, and how to use L, # and W in AWS EventBridge and Spring, with real run dates as examples.

Read article →
How-to Guide10 min read

How to Write EventBridge cron Expressions: What ? Means, Weekday Numbers, Japan Time and Converting from crontab

EventBridge cron expressions, used on AWS to run Lambda functions or ECS tasks on a schedule, look like Linux crontab but differ in the number of fields, the use of ?, the weekday numbers and the time zone. Write “0 9 * * 1-5” the crontab way and you get an error; copy the weekday numbers across and everything shifts by a day; and times are read in UTC, so you’re 9 hours off from Japan time. This article covers the six fields of an EventBridge cron expression and the ? rule, the weekday numbers, how to use L, W and #, how rate expressions differ, how Japan time works in rules versus Scheduler, and a conversion table for crontab, Kubernetes, Spring and systemd.

Read article →