Skip to content

⏰ cron Scheduled Tasks

crontab Basics

cron is Linux's built-in task scheduler. You tell it "when to execute what command," and it runs it on time for you.

bash
# Edit current user's scheduled tasks
crontab -e

# View current user's scheduled tasks
crontab -l

# View a specific user's scheduled tasks (requires root)
crontab -l -u www-data

# Delete all of the current user's scheduled tasks (dangerous!)
crontab -r

Time Format Explained

cron's time format has 5 fields, from left to right:

bash
# ┌───────────── minute (0-59)
# │ ┌───────────── hour (0-23)
# │ │ ┌───────────── day (1-31)
# │ │ │ ┌───────────── month (1-12)
# │ │ │ │ ┌───────────── day of week (0-7, 0 and 7 are both Sunday)
# │ │ │ │ │
  * * * * *  command

# Common examples:
30 2 * * *       /opt/backup.sh        # Every day at 2:30 AM
0 */4 * * *      /opt/check.sh          # Every 4 hours on the hour
0 9 * * 1-5      /opt/report.sh         # Weekdays at 9:00 AM
*/5 * * * *      /opt/ping.sh           # Every 5 minutes
0 0 1 * *        /opt/monthly.sh        # 1st of every month at midnight
30 8,12,18 * * * /opt/feed.sh           # Every day at 8:30, 12:30, 18:30
0 22 * * 1       /opt/weekly.sh         # Every Monday at 22:00

> ⚠️ Note: > ⚠️ Common pitfalls: cron's environment variables are limited to PATH=/usr/bin:/bin. If your script uses node, docker, etc., use absolute paths. cron sends output via email by default — if MAILTO is not set, errors may occur. Add MAILTO="" to disable. Scripts must have execute permission: chmod +x /opt/backup.sh

Complete crontab Template

bash
# ~/.crontab — recommended complete template
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=""

# === Database backup: daily at 2 AM ===
0 2 * * * /opt/scripts/db-backup.sh >> /var/log/db-backup.log 2>&1

# === Health check: every 5 minutes ===
*/5 * * * * /opt/scripts/health-check.sh 2>/dev/null

# === Log cleanup: every Sunday at 3 AM ===
0 3 * * 0 find /var/log/app -name "*.log" -mtime +30 -delete

# === Certificate renewal check: daily at 10 AM ===
0 10 * * * /opt/scripts/cert-renew.sh >> /var/log/cert-renew.log 2>&1

cron vs systemd timer

systemd also provides scheduled task functionality (.timer), which is more powerful than cron:

bash
# Create a systemd timer (alternative to cron)
cat > /etc/systemd/system/backup.timer << 'EOF'
[Unit]
Description=Daily Backup Timer

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=300

[Install]
WantedBy=timers.target
EOF

cat > /etc/systemd/system/backup.service << 'EOF'
[Unit]
Description=Database Backup

[Service]
Type=oneshot
ExecStart=/opt/scripts/db-backup.sh
User=root
EOF

systemctl daemon-reload
systemctl enable --now backup.timer

# View timer status
systemctl list-timers --all
Featurecronsystemd timer
LoggingManual redirection neededAutomatically recorded to journalctl
Missed executionWon't catch upPersistent=true will catch up
Dependency managementNoneCan wait for other services to start first
Resource limitsNoneCan limit CPU/memory
Learning curveVery lowMedium
Recommended forSimple tasks, familiar with cronProduction environments, need logging/catch-up