A cleanup job was supposed to run every five minutes. The crontab was saved at 10:03. The log showed 10:05, then 10:10. That is not a late start. The expression is tied to the clock, at minutes 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, and 55. Saving the file does not start a countdown. Classic cron also does not hold the next start while the previous process is still running, so a six-minute command overlaps itself. What follows is the five-field form used by Vixie cron and cronie, not a systemd timer and not Quartz.
Five fields, then the command
A standard line is five time fields and then the command. None of them is a seconds field.
| Field | Range | A star means |
|---|---|---|
| Minute | 0–59 | Every minute |
| Hour | 0–23 | Every hour |
| Day of month | 1–31 | Every day of the month |
| Month | 1–12 | Every month |
| Day of week | 0–7 | Every day of the week |
On Vixie cron and on cronie, Sunday is both 0 and 7. Monday is 1 and Friday is 5, so 1-5 is Monday through Friday. Some other schedulers accept only 0 for Sunday. Read crontab(5) on the host before using 7. Prefer numbers to names such as MON or JAN.
The fields use the daemon’s timezone, so 0 0 * * * is midnight there, not necessarily UTC. Honor CRON_TZ only if that host’s crontab(5) says so.
Every 5, 10, 15, and 30 minutes
Each line below is aligned to the clock, and each one includes minute 0.
*/5 * * * * # 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55
*/10 * * * * # 0, 10, 20, 30, 40, 50
*/15 * * * * # 0, 15, 30, 45
*/30 * * * * # 0 and 30
The edit time is not stored. A line installed at 10:03 still waits for 10:05, then 10:10.
5-59/5 * * * * starts the range at 5, so minute 0 is left out. Use it only when you mean to skip the top of the hour. For a plain every-five-minutes job, keep */5 * * * *.
Drop the step when you want an hour or a day instead.
0 * * * * # every hour, at minute 0
0 0 * * * # every day at 00:00
0 9 * * * # every day at 09:00
0 9 * * 1-5 # Monday through Friday at 09:00
0 * * * * fires 24 times a day, 0 0 * * * once at midnight, and 0 9 * * 1-5 on weekdays at 09:00 because day-of-month stays a star. The either-day rule starts only when both day fields are restricted. A day field that starts with *, including */2, is not restricted. See why cron runs on the wrong day.
How a step is counted
A step is a range plus /n. In the minute field, * means 0-59, so */5 is 0, then every fifth minute through 55. Twelve runs an hour.
In the hour field, 0 */2 * * * is minute 0 of every second hour: 00:00, 02:00, 04:00, and so on through 22:00.
Day of month starts at 1, not 0. On Vixie cron and cronie, * in that field is 1-31, so 0 0 */5 * * is midnight on the 1st, 6th, 11th, 16th, 21st, 26th, and 31st. It is not the dates divisible by 5 (the 5th, 10th, 15th, 20th, 25th, and 30th). If the daemon is not cronie, test that list. A cron expression generator shows the five fields. It does not simulate one daemon’s calendar, and it does not install the job.
Mistakes that move the run
Copy the five fields, not the sentence beside them. Crontab does not read “every five minutes.”
Do not add a seconds field in front. The other fields shift right. Quartz uses six fields, or seven with a year, and seconds come first. Spring uses that six-field form. EventBridge’s six fields are minutes, hours, day-of-month, month, day-of-week, and year, with no seconds field. Quartz and EventBridge both use ? in a day field. A five-field line matches neither shape.
Traditional Vixie cron does not skip a run because the previous process is still going. If the work must not overlap, take a lock in the command, for example with flock, and leave the schedule alone. systemd timers and queue workers can differ. This warning is about classic cron.
Cron’s PATH is often shorter than a login shell. Call the program by its absolute path. A stored “next run” in an API is often a Unix timestamp, not an expression. Read that number on the Unix timestamp converter. Do not paste it into the minute field.
*/5 cannot mean “five minutes from now.” Sleep in a process, or use a queue delay. The daemon still starts the command once, when the minute begins, not again at second 10 or 20.
Try it for one cycle
Point a throwaway line at a file you can delete.
*/5 * * * * date >> /tmp/cron-every-5.log
Wait until two lines are written. The minutes should be five apart, and each minute should be divisible by 5. Then delete the line. Some hosts log the start with journalctl -u cron. Others still use syslog. Use the log that machine keeps.
Full guide with the FAQ and a cron generator: https://kepttools.com/guides/cron-every-5-minutes
Top comments (0)