Back to Blog
Tutorial

The Ultimate Guide to Cron Jobs: A Beginner-to-Advanced Tutorial

Master cron jobs from zero to hero. The only guide you'll ever need—from basic syntax to advanced patterns, with real examples that actually work.

15 min read
By Cron Generator Team

The Ultimate Guide to Cron Jobs: A Beginner-to-Advanced Tutorial

If you've ever needed to run a script automatically—backups at 2 AM, reports every Monday, cache clearing every hour—you need cron. This is the complete guide that takes you from "What is cron?" to building complex automated workflows like a senior DevOps engineer.

No fluff. No outdated syntax. Just everything you need to master cron scheduling in 2025.

What is a Cron Job?

A cron job is a time-based task scheduler in Unix-like operating systems (Linux, macOS, BSD). It runs commands or scripts automatically at specified times, dates, or intervals without any human intervention.

Think of it as your server's personal assistant that never sleeps, never forgets, and executes tasks with perfect timing.

Real-World Use Cases

  • Automated Backups: Database dumps every night at 2 AM
  • Log Rotation: Clean up old logs weekly to save disk space
  • Report Generation: Send analytics emails every Monday morning
  • System Maintenance: Clear caches, update indexes, check for updates
  • Monitoring: Health checks every 5 minutes
  • Data Sync: Pull data from APIs hourly
  • Certificate Renewal: Check SSL certificates monthly
  • Cleanup Tasks: Delete temporary files daily

If it needs to happen on a schedule, cron can do it.

How Cron Works

The Cron Daemon

The cron daemon (or crond) is a background service that runs continuously on your system. Every minute, it wakes up, checks all scheduled tasks, and executes any that are due.

Check if cron is running:

# On most Linux systems
systemctl status cron

# Or
systemctl status crond

# On macOS
sudo launchctl list | grep cron

The Crontab File

Your scheduled tasks live in a crontab (cron table) file. Each user on the system can have their own crontab with different scheduled tasks.

Important: Never edit the crontab file directly with a text editor. Always use the crontab command to avoid syntax errors that could break all your scheduled tasks.

Cron Syntax: The Five Fields

Every cron expression consists of five fields followed by the command to execute:

* * * * * command-to-execute
│ │ │ │ │
│ │ │ │ └─── Day of Week (0-6, Sunday=0 or 7)
│ │ │ └───── Month (1-12)
│ │ └─────── Day of Month (1-31)
│ └───────── Hour (0-23)
└─────────── Minute (0-59)

Field Values

| Field | Values | Special Characters | |-------|--------|-------------------| | Minute | 0-59 | * , - / | | Hour | 0-23 | * , - / | | Day of Month | 1-31 | * , - / ? L W | | Month | 1-12 or JAN-DEC | * , - / | | Day of Week | 0-6 or SUN-SAT | * , - / ? L # |

Special Characters Explained

Asterisk (*) - "Every" or "Any"

  • * * * * * = Every minute
  • 0 * * * * = Every hour at minute 0

Comma (,) - List multiple values

  • 0 9,17 * * * = At 9 AM and 5 PM
  • 0 0 * * 1,5 = Midnight on Monday and Friday

Hyphen (-) - Range of values

  • 0 9-17 * * * = Every hour from 9 AM to 5 PM
  • 0 0 * * 1-5 = Midnight Monday through Friday

Slash (/) - Step values (intervals)

  • */15 * * * * = Every 15 minutes
  • 0 */6 * * * = Every 6 hours
  • */5 9-17 * * * = Every 5 minutes during business hours

Beginner Examples

Let's start with common patterns you'll use constantly.

Every Minute

* * * * * /path/to/script.sh

Use case: Testing, monitoring checks

Every Hour

0 * * * * /usr/bin/php /var/www/cleanup.php

Use case: Cache clearing, hourly sync

Every Day at Midnight

0 0 * * * /usr/local/bin/backup.sh

Use case: Daily backups, log rotation

Every Weekday at 9 AM

0 9 * * 1-5 /usr/bin/send-report.sh

Use case: Business reports, weekday notifications

Every Sunday at 2 AM

0 2 * * 0 /usr/local/bin/weekly-maintenance.sh

Use case: Weekly tasks, full system backups

First Day of Every Month

0 0 1 * * /usr/bin/monthly-billing.sh

Use case: Billing runs, monthly reports

Every 15 Minutes

*/15 * * * * /usr/bin/monitor-health.sh

Use case: Health checks, API polling

Every 6 Hours

0 */6 * * * /usr/bin/sync-data.sh

Use case: Data synchronization

Managing Your Crontab

View Current Crontab

crontab -l

Edit Crontab

crontab -e

This opens your crontab in the default editor (usually vi or nano).

Remove All Cron Jobs

crontab -r

Warning: This deletes EVERYTHING. No confirmation prompt.

Edit Another User's Crontab (as root)

sudo crontab -u username -e

Backup Your Crontab

crontab -l > ~/crontab-backup.txt

Always backup before making changes!

Restore from Backup

crontab ~/crontab-backup.txt

Intermediate Techniques

Using Environment Variables

Cron runs with a minimal environment. Set variables at the top of your crontab:

SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com

0 2 * * * /usr/local/bin/backup.sh

Common Variables:

  • SHELL: Which shell to use (default: /bin/sh)
  • PATH: Search path for executables
  • MAILTO: Email address for output (blank to disable)
  • HOME: Home directory for scripts

Redirecting Output

By default, cron emails you the output. Control where it goes:

# Redirect to log file
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# Redirect to null (silence everything)
0 2 * * * /usr/local/bin/backup.sh > /dev/null 2>&1

# Only log errors
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Understanding redirections:

  • >> = Append to file (don't overwrite)
  • 2>&1 = Redirect stderr to stdout
  • > /dev/null = Discard output

Multiple Commands

Run multiple commands in sequence:

# Using semicolons
0 2 * * * cd /var/backups && tar -czf backup.tar.gz /data && rm -f old-backup.tar.gz

# Using && (stop if one fails)
0 2 * * * command1 && command2 && command3

# Using a script (recommended)
0 2 * * * /usr/local/bin/run-all-backups.sh

Running Scripts with Specific Users

# Run as specific user
sudo crontab -u www-data -e

# Or use sudo in the command
0 2 * * * sudo -u www-data /var/www/cleanup.sh

Advanced Patterns

Business Hours Only

# Every 30 minutes from 9 AM to 5 PM, weekdays
*/30 9-17 * * 1-5 /usr/bin/business-task.sh

Multiple Specific Times

# At 6 AM, noon, 6 PM, and midnight
0 0,6,12,18 * * * /usr/bin/check-status.sh

Quarterly Tasks

# First day of each quarter at 1 AM
0 1 1 1,4,7,10 * /usr/bin/quarterly-report.sh

Every Other Hour During Workday

0 9-17/2 * * 1-5 /usr/bin/periodic-check.sh

This runs at 9 AM, 11 AM, 1 PM, 3 PM, 5 PM on weekdays.

Complex Combined Ranges

# Every 10 minutes during peak hours (9-11 AM and 2-5 PM)
*/10 9-11,14-17 * * 1-5 /usr/bin/peak-monitor.sh

Using Month Names

# Every Monday in January, April, July, October
0 9 * JAN,APR,JUL,OCT 1 /usr/bin/seasonal-task.sh

Using Day Names

# 8 PM every Friday
0 20 * * FRI /usr/bin/friday-tasks.sh

Special Cron Shortcuts

Some systems support these convenient shortcuts:

@reboot       # Run once at startup
@yearly       # 0 0 1 1 * (January 1st midnight)
@annually     # Same as @yearly
@monthly      # 0 0 1 * * (First of month)
@weekly       # 0 0 * * 0 (Sunday midnight)
@daily        # 0 0 * * * (Every midnight)
@midnight     # Same as @daily
@hourly       # 0 * * * * (Every hour)

Examples:

@reboot /usr/local/bin/startup-script.sh
@daily /usr/local/bin/backup.sh
@weekly /usr/local/bin/weekly-cleanup.sh

Note: Not all systems support these. Test first!

Real Production Examples

1. Database Backup with Rotation

# Backup MySQL database daily at 2:30 AM
30 2 * * * /usr/local/bin/mysql-backup.sh

# Delete backups older than 7 days at 3 AM
0 3 * * * find /var/backups/mysql -name "*.sql.gz" -mtime +7 -delete

Script: /usr/local/bin/mysql-backup.sh

#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/var/backups/mysql"
mysqldump -u root -p$MYSQL_PASSWORD mydatabase | gzip > $BACKUP_DIR/backup_$DATE.sql.gz

2. Log Rotation

# Compress logs weekly on Sunday at 1 AM
0 1 * * 0 gzip -f /var/log/app/*.log

# Delete compressed logs older than 30 days
0 2 * * 0 find /var/log/app -name "*.log.gz" -mtime +30 -delete

3. SSL Certificate Renewal (Let's Encrypt)

# Check and renew certificates at 3:30 AM on the 1st and 15th
30 3 1,15 * * certbot renew --quiet && systemctl reload nginx

4. System Health Monitoring

# Check disk space every hour
0 * * * * df -h | mail -s "Disk Space Report" admin@example.com

# Check if critical services are running every 5 minutes
*/5 * * * * systemctl is-active nginx || systemctl restart nginx

5. API Data Sync

# Fetch data from API every 15 minutes during business hours
*/15 9-17 * * 1-5 /usr/local/bin/sync-api-data.sh >> /var/log/api-sync.log 2>&1

6. Cache Warming

# Warm cache before traffic spike (7:30 AM weekdays)
30 7 * * 1-5 /usr/local/bin/warm-cache.sh

7. Cleanup Temporary Files

# Delete files in /tmp older than 2 days, every 6 hours
0 */6 * * * find /tmp -type f -mtime +2 -delete

Cron Best Practices

1. Always Use Absolute Paths

Wrong:

0 2 * * * backup.sh

Right:

0 2 * * * /usr/local/bin/backup.sh

Cron doesn't use your normal PATH. Be explicit.

2. Test Scripts Manually First

Before adding to cron:

# Run as the same user cron will use
/usr/local/bin/backup.sh

# Check exit code
echo $?

3. Add Logging

Always redirect output:

0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Add timestamps in your scripts:

#!/bin/bash
echo "[$(date)] Starting backup..."
# Your commands here
echo "[$(date)] Backup complete"

4. Use Locking for Long-Running Tasks

Prevent overlapping executions:

#!/bin/bash
LOCKFILE=/var/lock/backup.lock

if [ -f "$LOCKFILE" ]; then
    echo "Backup already running"
    exit 1
fi

touch "$LOCKFILE"
trap "rm -f $LOCKFILE" EXIT

# Your backup commands here
/usr/bin/mysqldump...

5. Set Email Notifications

Add to top of crontab:

MAILTO=admin@example.com

# Or disable emails
MAILTO=""

6. Comment Your Crontab

# Database backup - runs at 2 AM daily
0 2 * * * /usr/local/bin/backup.sh

# Log cleanup - runs weekly on Sunday
0 3 * * 0 /usr/local/bin/cleanup-logs.sh

7. Validate Before Saving

Use our cron expression generator to validate syntax before adding to crontab.

8. Use Source for Environment

If your script needs specific environment variables:

0 2 * * * /bin/bash -l -c 'source ~/.bashrc && /usr/local/bin/backup.sh'

9. Handle Errors Gracefully

#!/bin/bash
if ! /usr/bin/mysqldump database > backup.sql; then
    echo "Backup failed!" | mail -s "URGENT: Backup Failed" admin@example.com
    exit 1
fi

10. Monitor Cron Job Execution

Set up monitoring to alert if jobs don't run:

  • Use external monitoring (e.g., Cronitor, Healthchecks.io)
  • Write completion markers to files
  • Track execution in logs

System-Wide Cron Directories

Besides user crontabs, Linux systems have these directories:

/etc/cron.d/

Put files here with the same syntax as crontab, but with username:

# /etc/cron.d/myapp
0 2 * * * root /usr/local/bin/backup.sh

/etc/cron.hourly/

Scripts here run every hour. Just drop executable files.

/etc/cron.daily/

Scripts run once per day.

/etc/cron.weekly/

Scripts run once per week.

/etc/cron.monthly/

Scripts run once per month.

Note: These directories don't use cron syntax. Just make the file executable:

chmod +x /etc/cron.daily/backup.sh

Troubleshooting Cron Jobs

Check if Cron is Running

systemctl status cron
ps aux | grep cron

View Cron Logs

# On Ubuntu/Debian
grep CRON /var/log/syslog

# On CentOS/RHEL
tail -f /var/log/cron

# On macOS
log show --predicate 'process == "cron"' --last 1h

Test Your Cron Expression

Use our decoder tool to see when your cron will run next.

Common Issues

Job not running at all:

  • Check cron syntax with our validator
  • Verify cron daemon is running
  • Check user permissions
  • Look for syntax errors in crontab

Script works manually but not in cron:

  • Use absolute paths everywhere
  • Set environment variables
  • Check script permissions (chmod +x)
  • Add logging to see what's happening

No output/emails:

  • Check MAILTO setting
  • Verify mail system is configured
  • Check spam folder
  • Add explicit logging

Advanced: Anacron for Laptops

Cron only runs jobs at specific times. If your computer is off, the job is missed. Anacron runs missed jobs when the system boots.

Install:

sudo apt install anacron

Edit /etc/anacrontab:

# period  delay  job-id  command
1         5      daily-backup  /usr/local/bin/backup.sh
7         10     weekly-update  /usr/local/bin/update.sh
  • period: Days between runs
  • delay: Minutes to wait after boot
  • job-id: Unique identifier
  • command: What to run

Cron in Docker Containers

Running cron in Docker requires special setup:

Dockerfile:

FROM ubuntu:22.04

# Install cron
RUN apt-get update && apt-get install -y cron

# Copy crontab file
COPY crontab /etc/cron.d/myapp-cron
RUN chmod 0644 /etc/cron.d/myapp-cron
RUN crontab /etc/cron.d/myapp-cron

# Run cron in foreground
CMD ["cron", "-f"]

crontab file:

*/5 * * * * /usr/local/bin/task.sh >> /var/log/cron.log 2>&1

Cron Alternatives

While cron is the standard, consider these alternatives for specific use cases:

Systemd Timers

Modern alternative to cron on systemd-based Linux:

# More precise timing
# Better logging integration
# Service dependencies

Kubernetes CronJobs

For containerized environments:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: backup
spec:
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: backup:latest

Cloud Schedulers

  • AWS EventBridge
  • Google Cloud Scheduler
  • Azure Logic Apps

Use when you need:

  • Serverless execution
  • Cloud-native integration
  • No server maintenance

Quick Reference Card

# Field order
# * * * * * command
# │ │ │ │ │
# │ │ │ │ └─ Day of Week (0-6)
# │ │ │ └─── Month (1-12)
# │ │ └───── Day of Month (1-31)
# │ └─────── Hour (0-23)
# └───────── Minute (0-59)

# Common patterns
*/5 * * * *       # Every 5 minutes
0 * * * *         # Every hour
0 0 * * *         # Daily at midnight
0 0 * * 0         # Weekly on Sunday
0 0 1 * *         # Monthly on 1st
0 9-17 * * 1-5    # Weekdays, business hours

# Special strings
@reboot           # At startup
@daily            # Once per day
@weekly           # Once per week
@monthly          # Once per month
@yearly           # Once per year

# Management commands
crontab -l        # List jobs
crontab -e        # Edit jobs
crontab -r        # Remove all jobs
crontab -u user   # For specific user

Next Steps

You now know everything you need to master cron jobs. But syntax is only half the battle.

Want to create perfect cron expressions without memorizing syntax?

Use our visual cron generator to:

  • Build expressions with dropdowns (no syntax errors)
  • See human-readable explanations instantly
  • Test patterns before deploying
  • Save and share configurations

Or paste existing cron expressions into our decoder to understand exactly what they do.

Stop fighting with syntax. Start automating like a pro.


Related Articles

Continue Learning:

Advanced Topics:


This guide covers standard cron (Vixie cron). Some systems use variants with slight differences. Always test on your target system.