DEV Community

Cover image for Cron Jobs Explained: Scheduling Automated Tasks on Linux
Raizan
Raizan

Posted on • Originally published at chasebot.online

Cron Jobs Explained: Scheduling Automated Tasks on Linux

What You'll Need

  • n8n Cloud or self-hosted n8n (optional, for automation integration)
  • Hetzner VPS, Contabo VPS, or DigitalOcean for running cron jobs
  • Namecheap if you need a domain for your automation
  • Linux server access (Ubuntu 20.04 LTS or later recommended)
  • Basic command-line familiarity

Table of Contents

Understanding Cron: The Basics

I'll be honest—when I first encountered cron jobs, I thought they were some obscure DevOps sorcery. They're actually one of the simplest yet most powerful tools in Linux. A cron job is just a scheduled task that runs automatically at specific times or intervals without you touching a keyboard. It's been the backbone of server automation since 1975, and it still works beautifully today.

Think of cron as your personal assistant that never sleeps. You give it instructions once, and it executes them endlessly—every minute, every hour, every month, or whenever you specify. Whether you're backing up databases, clearing log files, sending status reports, or pulling crypto prices for alerts, cron handles it silently in the background.

The beauty of cron is its simplicity. Unlike more complex automation platforms, it requires no UI, no cloud connection, and no monthly subscription. If you've got a Linux server—whether it's a Hetzner VPS or a DigitalOcean droplet—you've already got cron built in.

However, if you're managing dozens of workflows across multiple systems, you might eventually want to explore solutions like n8n Cloud, which centralizes your automation logic. But let's not get ahead of ourselves. Cron is perfect for many use cases, and understanding it is fundamental.

Crontab Syntax Breakdown

The magic happens in a file called a crontab (cron table). Each line in your crontab represents one scheduled task, and each line follows this exact format:

┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 7) (0 and 7 are Sunday)
│ │ │ │ │
│ │ │ │ │
* * * * * command-to-execute
Enter fullscreen mode Exit fullscreen mode

Let me break this down with actual examples so you see how it works:

0 2 * * * /home/user/backup.sh

This runs /home/user/backup.sh at 2:00 AM every single day. The first 0 means minute 0 (top of the hour), 2 is 2 AM, and the three asterisks mean "every day, every month, any day of week."

*/15 * * * * /usr/bin/python3 /home/user/check_status.py

The */15 means "every 15 minutes." This Python script runs four times per hour, all day, every day.

0 0 1 * * /home/user/monthly_report.sh

This runs on the first day of every month at midnight. Perfect for monthly tasks.

30 3 * * 1 /home/user/weekly_backup.sh

This runs every Monday at 3:30 AM. The 1 represents Monday (0=Sunday, 1=Monday, etc.).

Here's a quick reference table for common time expressions:

@yearly      0 0 1 1 *     (once per year on January 1st)
@monthly     0 0 1 * *     (once per month on the 1st)
@weekly      0 0 * * 0     (once per week on Sunday at midnight)
@daily       0 0 * * *     (once per day at midnight)
@hourly      0 * * * *     (once per hour)
@reboot      -             (when the system boots up)
Enter fullscreen mode Exit fullscreen mode

These shortcuts make crontabs more readable. @hourly is much cleaner than 0 * * * *.

Creating and Managing Your First Cron Job

Let's get practical. I'm going to walk you through creating a real cron job from scratch.

Step 1: Open Your Crontab

On your Linux server, open the crontab editor:

crontab -e
Enter fullscreen mode Exit fullscreen mode

This opens your personal crontab in your default editor (usually nano or vim). If it's your first time, you'll see a blank file with some commented instructions at the top.

Step 2: Write Your Script

First, let's create the script you want to run. I'll create a simple backup script. Open a new file:

nano /home/user/backup_logs.sh
Enter fullscreen mode Exit fullscreen mode

Add this content:

#!/bin/bash

BACKUP_DIR="/backups"
SOURCE_DIR="/var/log"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

tar -czf $BACKUP_DIR/logs_backup_$DATE.tar.gz $SOURCE_DIR

find $BACKUP_DIR -name "logs_backup_*.tar.gz" -mtime +7 -delete

echo "Backup completed at $(date)" >> /var/log/backup.log
Enter fullscreen mode Exit fullscreen mode

Save the file (Ctrl+O, Enter, Ctrl+X in nano), then make it executable:

chmod +x /home/user/backup_logs.sh
Enter fullscreen mode Exit fullscreen mode

Step 3: Add the Cron Job

Now open your crontab again:

crontab -e
Enter fullscreen mode Exit fullscreen mode

Add this line at the bottom:

0 3 * * * /home/user/backup_logs.sh
Enter fullscreen mode Exit fullscreen mode

This runs your backup script every day at 3:00 AM.

Step 4: Verify It's Scheduled

List your cron jobs to confirm they were added:

crontab -l
Enter fullscreen mode Exit fullscreen mode

You should see your new job listed. That's it—you're done. The script will run automatically from now on.

💡 Fast-Track Your Project: Don't want to configure this yourself? I build custom n8n pipelines and bots. Message me with code SYS3-DEVTO.

Real-World Examples and Use Cases

Let me show you some practical cron jobs I've actually used in production environments. These patterns solve real problems.

Database Backups Every 6 Hours

0 */6 * * * /usr/bin/mysqldump -u root -pYourPassword database_name > /backups/db_$(date +\%Y\%m\%d_\%H\%M\%S).sql
Enter fullscreen mode Exit fullscreen mode

This backs up your MySQL database every 6 hours. The backticks escape the date command so it's evaluated at runtime.

Clean Up Old Log Files

0 2 * * * find /var/log/nginx -name "*.log" -mtime +30 -delete
Enter fullscreen mode Exit fullscreen mode

Runs at 2 AM daily, deleting nginx logs older than 30 days. Essential for preventing disk space issues.

Sync Files to Remote Server

30 4 * * * rsync -avz --delete /home/user/data/ user@remote.server:/backup/data/
Enter fullscreen mode Exit fullscreen mode

Syncs your data directory to a remote server at 4:30 AM every day. Great for distributed backups.

Check Website Uptime

*/5 * * * * /home/user/check_uptime.sh
Enter fullscreen mode Exit fullscreen mode

Here's what check_uptime.sh might look like:

#!/bin/bash

WEBSITE="https://example.com"
LOGFILE="/var/log/uptime_check.log"

if curl -s --max-time 5 "$WEBSITE" > /dev/null; then
    echo "$(date) - $WEBSITE is UP" >> $LOGFILE
else
    echo "$(date) - $WEBSITE is DOWN - sending alert" >> $LOGFILE
    echo "Website down!" | mail -s "Alert: $WEBSITE Down" admin@example.com
fi
Enter fullscreen mode Exit fullscreen mode

This checks every 5 minutes and sends an email if the site is down.

Generate Daily Reports

0 8 * * * /usr/bin/python3 /home/user/generate_report.py
Enter fullscreen mode Exit fullscreen mode

Run a Python script at 8 AM to generate reports. Here's a sample script:

#!/usr/bin/env python3

import subprocess
from datetime import datetime

report_date = datetime.now().strftime("%Y-%m-%d")
output_file = f"/reports/report_{report_date}.txt"

with open(output_file, "w") as f:
    f.write(f"Daily Report for {report_date}\n")
    f.write("=" * 40 + "\n")

    disk_usage = subprocess.check_output(["df", "-h"], text=True)
    f.write("Disk Usage:\n")
    f.write(disk_usage)
    f.write("\n")

    memory = subprocess.check_output(["free", "-h"], text=True)
    f.write("Memory Status:\n")
    f.write(memory)

print(f"Report generated: {output_file}")
Enter fullscreen mode Exit fullscreen mode

Restart Services If Down

*/10 * * * * /home/user/check_service.sh
Enter fullscreen mode Exit fullscreen mode

Here's the script:

#!/bin/bash

SERVICE_NAME="nginx"

if ! systemctl is-active --quiet $SERVICE_NAME; then
    echo "$(date) - $SERVICE_NAME was down, restarting..." >> /var/log/service_restarts.log
    systemctl restart $SERVICE_NAME
fi
Enter fullscreen mode Exit fullscreen mode

Checks every 10 minutes and restarts nginx if it's not running.

If you're automating data collection across multiple systems, you might eventually want to centralize your workflows. Check out our guide on How to Set Up a VPS for Automation (Hetzner vs Contabo vs Railway) to understand hosting options that work well with automation systems.

Debugging and Monitoring Cron Jobs

Here's where most people struggle. A cron job runs silently, and when something breaks, you won't know unless you look at the logs.

Check If Cron Daemon Is Running

sudo service cron status
Enter fullscreen mode Exit fullscreen mode

On some systems:

sudo systemctl status cron
Enter fullscreen mode Exit fullscreen mode

If it's not running:

sudo systemctl start cron
sudo systemctl enable cron
Enter fullscreen mode Exit fullscreen mode

View Cron Logs (Ubuntu/Debian)

sudo grep CRON /var/log/syslog
Enter fullscreen mode Exit fullscreen mode

Or on newer systems:

sudo journalctl -u cron --no-pager
Enter fullscreen mode Exit fullscreen mode

This shows all cron activity. You'll see lines like:

Nov 15 03:00:01 myserver CRON[12345]: (user) CMD (/home/user/backup_logs.sh)
Enter fullscreen mode Exit fullscreen mode

Capture Output and Errors

Modify your crontab to save output:

0 3 * * * /home/user/backup_
Enter fullscreen mode Exit fullscreen mode

Originally published on Automation Insider.

Top comments (0)