Cron Jobs Explained: Scheduling Automated Tasks on Linux

DevOps #linux#cron#automation#devops#sysadmin
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

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)

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

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

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

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

chmod +x /home/user/backup_logs.sh

Step 3: Add the Cron Job

Now open your crontab again:

crontab -e

Add this line at the bottom:

0 3 * * * /home/user/backup_logs.sh

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

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-HUGO.

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

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

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/

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

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

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

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}")

Restart Services If Down

*/10 * * * * /home/user/check_service.sh

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

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

On some systems:

sudo systemctl status cron

If it’s not running:

sudo systemctl start cron
sudo systemctl enable cron

View Cron Logs (Ubuntu/Debian)

sudo grep CRON /var/log/syslog

Or on newer systems:

sudo journalctl -u cron --no-pager

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)

Capture Output and Errors

Modify your crontab to save output:

0 3 * * * /home/user/backup_

Want to automate this yourself?

Start with n8n Cloud (free tier available) or self-host on a Hetzner VPS for full control.

📬 Get Weekly Automation Tips

One email per week with tutorials, tools, and workflows. No spam, unsubscribe anytime.

Subscribe Free →