Learn how to use cron to schedule automated tasks on Ubuntu — from basic syntax to real-world examples like backups, cleanup scripts, and API calls.
A cron expression has 5 fields:
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-7, 0 and 7 = Sunday)
│ │ │ │ │
* * * * * command
Common patterns:
* * * * * # Every minute
*/5 * * * * # Every 5 minutes
0 * * * * # Every hour (at minute 0)
0 0 * * * # Every day at midnight
0 0 * * 0 # Every Sunday at midnight
0 0 1 * * # First day of every month
30 2 * * 1-5 # Weekdays at 2:30 AM
Edit your crontab:
crontab -e # Edit current user's crontab
sudo crontab -e # Edit root's crontab
crontab -l # List current cron jobs
Automatically back up your PostgreSQL database every night:
# Create backup script
sudo nano /usr/local/bin/db-backup.sh
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=/home/deploy/backups
DB_NAME=myapp
mkdir -p $BACKUP_DIR
# Dump database
pg_dump $DB_NAME | gzip > $BACKUP_DIR/db_${DATE}.sql.gz
# Delete backups older than 7 days
find $BACKUP_DIR -name "db_*.sql.gz" -mtime +7 -delete
echo "Backup completed: db_${DATE}.sql.gz"
chmod +x /usr/local/bin/db-backup.sh
Schedule it:
crontab -e
# Add this line:
0 3 * * * /usr/local/bin/db-backup.sh >> /var/log/db-backup.log 2>&1
This runs at 3 AM daily, compresses the backup, keeps only the last 7 days, and logs the output.
Clean up temporary files that file conversion tools create:
# Every hour, delete temp files older than 1 hour
0 * * * * find /tmp/reformat -type f -mmin +60 -delete 2>/dev/null
# Every day at 4am, delete old log files
0 4 * * * find /var/log/myapp -name "*.log" -mtime +30 -delete
# Every 15 minutes, check disk space and alert
*/15 * * * * /usr/local/bin/disk-check.sh
Monitor your application and restart it if it goes down:
sudo nano /usr/local/bin/health-check.sh
#!/bin/bash
SERVICE="myapi"
URL="http://127.0.0.1:8000/health"
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 $URL)
if [ "$HTTP_CODE" != "200" ]; then
echo "$(date): $SERVICE is down (HTTP $HTTP_CODE). Restarting..." >> /var/log/health-check.log
systemctl restart $SERVICE
fi
chmod +x /usr/local/bin/health-check.sh
crontab -e
# Check every 2 minutes
*/2 * * * * /usr/local/bin/health-check.sh
This is a simple but effective uptime monitor. For production systems, pair this with an external monitoring service like UptimeRobot or Betterstack.
Cron jobs fail silently by default. Here's how to debug:
1. Always redirect output to a log file:* * * * * /path/to/script.sh >> /var/log/myjob.log 2>&1
2. Check cron daemon logs:
grep CRON /var/log/syslog | tail -20
3. Common problems:
# Bad
python script.py
# Good
/usr/bin/python3 /home/deploy/script.py
.bashrc. Source them: * * * * * source /home/deploy/.env && /path/to/script.sh
chmod +x /path/to/script.sh
4. Test by running the exact cron command manually:
/bin/bash -c '/path/to/your/cron/command'