Cron on Linux: crontab Syntax and Schedule Examples

Cron is the Linux job scheduler. It runs commands and scripts on a schedule: backups at night, temporary file clean-up once a week, a certificate check every day.
Managing jobs
Every user has their own job table — the crontab.
crontab -e # open the table in an editor
crontab -l # show current jobs
crontab -r # delete all of the user's jobs
To edit another user’s jobs, add -u: sudo crontab -u www-data -e.
Line format
* * * * * command
│ │ │ │ │
│ │ │ │ └─ day of week (0–7, where 0 and 7 are Sunday)
│ │ │ └─── month (1–12)
│ │ └───── day of month (1–31)
│ └─────── hour (0–23)
└───────── minute (0–59)
Each field accepts:
*— any value;5— a specific value;1,15— a list;1-5— a range;*/10— every 10 units.
Schedule examples
| Schedule | When it runs |
|---|---|
* * * * * |
every minute |
*/5 * * * * |
every 5 minutes |
0 * * * * |
at the start of every hour |
30 3 * * * |
daily at 03:30 |
0 9 * * 1-5 |
on weekdays at 09:00 |
0 0 1 * * |
at midnight on the first day of each month |
0 4 * * 0 |
on Sundays at 04:00 |
There are shortcuts for common cases: @reboot (at system start-up), @hourly, @daily, @weekly, @monthly.
Practical jobs
A daily site backup at 02:00:
0 2 * * * tar -czf /backup/site-$(date +\%F).tar.gz /var/www/site
Directory sync every 15 minutes:
*/15 * * * * rsync -a /var/www/ backup@203.0.113.20:/backup/www/
Run a script after the server reboots:
@reboot /opt/scripts/start.sh
Output and logs
By default cron tries to email a command’s output, and on a server without a mail service it is lost. Redirect the output to a file:
0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
2>&1 sends error messages to the same file. The system journal shows that jobs were started:
journalctl -u cron --since today # Debian, Ubuntu
journalctl -u crond --since today # AlmaLinux, Rocky Linux, RHEL
Preventing overlapping runs
If a job takes longer than the interval between runs, copies start piling up. The flock utility starts the command only if the previous instance has finished:
*/5 * * * * flock -n /tmp/sync.lock /opt/scripts/sync.sh
Common mistakes
- The command works in a terminal but not in cron. Cron has a minimal environment and a short
PATH. Use full paths to programs (/usr/bin/php) or setPATHon the first line of the crontab. - The
%character. In a crontab it means a newline. Escape it in commands:date +\%F. - Relative paths. A job starts in the user’s home directory. Use absolute paths or
cd /path && command. - The script is not executable. Run
chmod +x script.shand add#!/bin/bashas the first line. - Time zone. Cron uses system time. Check it with
timedatectl.
System jobs
Besides user tables there are system ones:
/etc/crontaband files in/etc/cron.d/— the same format with an extra user name field before the command;/etc/cron.daily/,/etc/cron.weekly/,/etc/cron.monthly/— scripts in these directories run at the corresponding interval.
Cron and systemd timers
On modern distributions some jobs are handled by systemd timers. They can run jobs missed while the server was down and keep a detailed log, but need two files instead of one line. For simple schedules on a VPS, cron is still the quickest option. List active timers with systemctl list-timers.


