Linux Cron Jobs: Complete Guide to Scheduling Tasks
๐ 10 min read ยท Linux & Automation ยท Try Cron Generator โ
What is Cron?
Cron is a time-based job scheduler built into Unix and Linux operating systems. It allows you to run scripts, commands, and programs automatically at specified times and intervals โ without any manual intervention. The name comes from the Greek word chronos (time).
Cron is used for everything from nightly database backups and log rotation to sending scheduled emails, running data imports, clearing caches, and monitoring system health. If a task needs to run on a schedule, cron is almost always the right tool on Linux.
How Cron Works
The cron daemon (crond) runs continuously in the background. Every minute it checks a set of configuration files called crontabs to see if any scheduled jobs need to run. If a job is due, it executes it as the user who owns that crontab.
Each user on a Linux system can have their own crontab. There is also a system-wide crontab at /etc/crontab and drop-in directories at /etc/cron.d/, /etc/cron.daily/, /etc/cron.hourly/, /etc/cron.weekly/, and /etc/cron.monthly/.
Crontab Syntax
Each line in a crontab file represents one scheduled job and follows this format:
โโโโโโโโโโโโโโ minute (0โ59) โ โโโโโโโโโโโโโโ hour (0โ23) โ โ โโโโโโโโโโโโโโ day of month (1โ31) โ โ โ โโโโโโโโโโโโโโ month (1โ12) โ โ โ โ โโโโโโโโโโโโโโ day of week (0โ6, Sunday=0) โ โ โ โ โ * * * * * command to execute
A complete cron job line looks like this:
0 2 * * * /home/user/backup.sh
This runs backup.sh every day at 2:00 AM.
Cron Special Characters
*AsteriskMatches every value. In the minute field, * means every minute.
* * * * * โ every minute
,CommaSpecifies a list of values.
0 9,17 * * * โ at 9:00 AM and 5:00 PM
-HyphenSpecifies a range of values.
0 9-17 * * * โ every hour from 9 AM to 5 PM
/SlashSpecifies step values (every N).
*/15 * * * * โ every 15 minutes
@At signShorthand for common schedules.
@daily, @hourly, @reboot, @weekly, @monthly
Common Cron Expression Examples
| Expression | Meaning |
|---|---|
* * * * * | Every minute |
*/5 * * * * | Every 5 minutes |
0 * * * * | Every hour (at :00) |
0 0 * * * | Every day at midnight |
0 9 * * 1-5 | Weekdays at 9:00 AM |
0 0 * * 0 | Every Sunday at midnight |
0 0 1 * * | First day of every month at midnight |
0 0 1 1 * | January 1st at midnight (yearly) |
30 6 * * 1,3,5 | Mon, Wed, Fri at 6:30 AM |
0 */2 * * * | Every 2 hours |
@reboot | Once at system startup |
@daily | Once a day (same as 0 0 * * *) |
Managing Crontabs
Use the crontab command to manage your scheduled jobs:
crontab -eOpen your crontab in the default editor (nano or vi). Creates it if it does not exist.
crontab -lList all cron jobs for the current user.
crontab -rRemove (delete) your entire crontab. Use with caution โ this cannot be undone.
crontab -u username -eEdit the crontab for a specific user (requires root/sudo).
sudo crontab -eEdit the root user's crontab for system-level tasks.
Real-World Cron Job Examples
# Backup database every day at 2 AM 0 2 * * * /usr/bin/mysqldump -u root mydb > /backups/db_$(date +%F).sql # Clear application cache every hour 0 * * * * /var/www/app/scripts/clear-cache.sh # Send weekly report every Monday at 8 AM 0 8 * * 1 /home/deploy/scripts/weekly-report.py # Rotate logs every Sunday at midnight 0 0 * * 0 /usr/sbin/logrotate /etc/logrotate.conf # Check disk usage every 30 minutes */30 * * * * /home/admin/scripts/disk-alert.sh # Run database cleanup on the 1st of every month at 3 AM 0 3 1 * * /usr/bin/php /var/www/app/artisan db:cleanup # Restart a service every day at 4 AM (low traffic window) 0 4 * * * systemctl restart nginx # Pull latest code and deploy every weekday at 6 AM 0 6 * * 1-5 cd /var/www/app && git pull && npm run build
Environment Variables in Cron
Cron runs with a minimal environment โ it does not load your .bashrc or .profile. This is the most common reason cron jobs fail when they work fine in the terminal.
You can set environment variables at the top of your crontab:
SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin MAILTO=admin@example.com # Now your jobs run with the correct PATH 0 2 * * * /home/user/backup.sh
โ ๏ธ Common Pitfall
Always use absolute paths in cron commands. Instead of python script.py, use /usr/bin/python3 /home/user/script.py. Cron's PATH does not include your user directories.
Redirecting Cron Output
By default, cron emails output to the user. You can redirect it to a log file or suppress it entirely:
# Redirect all output to a log file 0 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1 # Suppress all output (silent) 0 2 * * * /home/user/backup.sh > /dev/null 2>&1 # Log stdout but discard errors 0 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>/dev/null
Debugging Cron Jobs
When a cron job does not run as expected, here is how to debug it:
- Check the system cron log:
grep CRON /var/log/syslogorjournalctl -u cron - Verify the cron daemon is running:
systemctl status cron - Test your script manually with the same user:
sudo -u www-data /path/to/script.sh - Check file permissions โ the script must be executable:
chmod +x /path/to/script.sh - Add logging to your script to capture what happens during execution
- Set
MAILTO=your@email.comin crontab to receive error emails
Cron vs Systemd Timers
Modern Linux systems also support systemd timers as an alternative to cron. Here is a quick comparison:
Cron
- Simple, widely supported
- Works on all Unix/Linux systems
- Easy to set up with crontab -e
- No dependency tracking
- Limited logging
Systemd Timers
- Full journald logging
- Dependency management
- Can catch up missed runs
- More complex to configure
- Only on systemd-based systems
For most use cases, cron is simpler and perfectly adequate. Use systemd timers when you need advanced logging, dependency management, or missed-run recovery.
Build Cron Expressions Visually
Use the DevBench Cron Generator to create and understand cron expressions without memorizing the syntax.