Back to Blog

Scheduling on Ubuntu: when to use cron vs systemd timers

Complete tutorial on cron/systemd timers in Ubuntu. Learn crontab syntax, OnCalendar, service/timer units, accuracy.

Scheduling on Ubuntu: when to use cron vs systemd timers

Scheduling on Ubuntu: When to Use Cron vs Systemd Timers

Scheduling tasks on Linux is a fundamental aspect of system administration and automation, allowing users to execute commands or scripts at predefined times or intervals. Two of the most prominent tools for scheduling tasks in Ubuntu are cron and systemd timers. Understanding when to use each can significantly enhance your workflow, streamline system maintenance, and ensure that automated tasks run efficiently.

Cron is a time-based job scheduler that has been a staple in Unix-like systems for decades. It allows for repetitive execution of scripts or commands based on defined schedules. On the other hand, systemd timers provide a more modern approach to scheduling, integrated with the systemd init system. They offer more flexibility, including the ability to trigger jobs based on system events and dependencies.

Choosing between these two tools depends on various factors such as the complexity of tasks, required accuracy, and the environment in which they operate. This tutorial will guide you through both tools, highlighting their syntax, use cases, and practical examples to empower you in automating tasks in Ubuntu.

Prerequisites

  • Ubuntu Version: This tutorial is applicable for Ubuntu 16.04 and later.
  • Required Packages: Ensure that cron is installed (it is typically pre-installed). For systemd timers, you need the default systemd package.
  • Permissions: Root or sudo privileges may be required to schedule certain tasks.
  • Risks: Be cautious with the commands you schedule; incorrect commands can lead to data loss or system instability.

Core Concepts

Terminology

  • Cron: A time-based job scheduler in Unix-like operating systems.
  • Crontab: A file where cron jobs are defined. Each user can have their own crontab.
  • Systemd: A system and service manager for Linux operating systems.
  • Timer Units: Files in systemd that define the timer's properties and behavior.

Architecture

  • Cron Architecture: Cron uses a daemon process (crond) that runs in the background and checks the crontabs every minute.
  • Systemd Timer Architecture: Systemd timers consist of two files: a timer unit file and a service unit file that defines the job to execute.

When to Use

  • Cron: Best for simple, time-based scheduling tasks without complex dependencies.
  • Systemd Timers: Ideal for service management, dependency handling, and event-based scheduling.

Limits

  • Cron: Limited to time-based scheduling; lacks event handling capabilities.
  • Systemd Timers: More complex; may require understanding of systemd units.

Syntax/Commands

Command Description Flags/Parameters
crontab -e Edit the user's crontab -u <user> (for other users)
systemctl start <service> Start a systemd service --now (start and enable the timer)
systemctl status <timer> Check the status of a timer N/A

Practical Examples

Using Cron

  1. Basic Cron Job

    Schedule a job to run every day at 3 AM.

    crontab -e
    # Add the following line:
    0 3 * * * /path/to/your/script.sh
    
  2. Cron Job with Logging

    Log output to a file.

    crontab -e
    # Add the following line:
    0 3 * * * /path/to/your/script.sh >> /path/to/logfile.log 2>&1
    
  3. Cron Job Every 5 Minutes

    Run a script every 5 minutes.

    crontab -e
    # Add the following line:
    */5 * * * * /path/to/your/script.sh
    
  4. Cron Job on Specific Days

    Schedule a job every Monday and Friday at noon.

    crontab -e
    # Add the following line:
    0 12 * * 1,5 /path/to/your/script.sh
    

Using Systemd Timers

  1. Creating a Simple Timer

    Create a service and timer to run a script every hour.

    # Create the service file
    sudo nano /etc/systemd/system/my-script.service
    
    [Unit]
    Description=Run my script
    
    [Service]
    ExecStart=/path/to/your/script.sh
    
    # Create the timer file
    sudo nano /etc/systemd/system/my-script.timer
    
    [Unit]
    Description=Runs my-script.service every hour
    
    [Timer]
    OnCalendar=hourly
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    
    # Enable and start the timer
    sudo systemctl enable my-script.timer
    sudo systemctl start my-script.timer
    
  2. Check Timer Status

    View the status of your timer.

    systemctl status my-script.timer
    
  3. Run Timer Immediately

    To run the timer immediately, use the following command:

    sudo systemctl start my-script.service
    
  4. View Timer Logs

    Check logs for the executed job.

    journalctl -u my-script.service
    

Real-World Scenarios

  1. Automated Backups: Use cron to schedule daily backups of crucial directories. A simple cron job could copy files to a backup location every night, ensuring data safety.

  2. Monitoring System Resources: Set a systemd timer to run a monitoring script every hour, checking CPU and memory usage, and logging the results for performance analysis.

  3. Package Updates: Schedule a cron job to check for software updates and apply them weekly. This ensures your system stays secure and up to date without manual intervention.

Best Practices

  1. Use Absolute Paths: Always use absolute paths in scripts and commands to avoid path issues.

  2. Log Outputs: Redirect outputs to log files for debugging and monitoring.

  3. Test Scripts Manually: Always test your scripts manually before scheduling them to ensure they work as expected.

  4. Use Systemd for Complex Tasks: Prefer systemd timers for tasks that depend on specific events, such as network availability.

  5. Keep Crontab Organized: Comment your crontab entries for clarity, especially when managing multiple jobs.

Common Errors

  1. Error: no crontab for user

    • Cause: No crontab file exists for the user.
    • Fix: Run crontab -e to create one.
  2. Error: command not found

    • Cause: The command or script is not in the PATH.
    • Fix: Use absolute paths in your cron job.
  3. Error: failed to start my-script.service: Unit my-script.service not found.

    • Cause: The service file is not created or not loaded.
    • Fix: Ensure the service file exists and reload systemd with systemctl daemon-reload.
  4. Error: failed to parse OnCalendar

    • Cause: Incorrect syntax in the timer file.
    • Fix: Double-check the OnCalendar syntax in your timer file.

Related Commands

Command Description
at Schedule one-time tasks
batch Schedule tasks when system load is low
anacron Run scheduled tasks missed while system was off

Automation Script

Here’s a complete bash script that sets up a cron job and a systemd timer for running a backup script.

#!/bin/bash

# Backup script setup
BACKUP_SCRIPT="/path/to/backup.sh"
CRON_JOB="0 2 * * * $BACKUP_SCRIPT"

# Create backup script
echo "#!/bin/bash" > $BACKUP_SCRIPT
echo "tar -czf /path/to/backup-\$(date +'%Y%m%d').tar.gz /path/to/directory" >> $BACKUP_SCRIPT
chmod +x $BACKUP_SCRIPT

# Add cron job
( crontab -l; echo "$CRON_JOB" ) | crontab -

# Create systemd service
SERVICE_FILE="/etc/systemd/system/backup.service"
echo "[Unit]" > $SERVICE_FILE
echo "Description=Backup Service" >> $SERVICE_FILE
echo "[Service]" >> $SERVICE_FILE
echo "ExecStart=$BACKUP_SCRIPT" >> $SERVICE_FILE

# Create systemd timer
TIMER_FILE="/etc/systemd/system/backup.timer"
echo "[Unit]" > $TIMER_FILE
echo "Description=Backup Timer" >> $TIMER_FILE
echo "[Timer]" >> $TIMER_FILE
echo "OnCalendar=daily" >> $TIMER_FILE
echo "[Install]" >> $TIMER_FILE
echo "WantedBy=timers.target" >> $TIMER_FILE

# Enable and start the timer
systemctl enable backup.timer
systemctl start backup.timer

echo "Backup job scheduled with cron and systemd."

Conclusion

In this tutorial, we explored the differences between cron and systemd timers, their respective syntax, and practical examples. We discussed best practices for scheduling tasks and addressed common errors that may arise.

As you delve further into task scheduling, consider the nature of the tasks you need to automate and choose the appropriate tool accordingly. For more complex, event-driven tasks, systemd timers may be your best bet, while cron remains a reliable solution for straightforward time-based scheduling.

Next Steps

  • Explore more about systemd unit files and their options.
  • Experiment with combining cron and systemd for different use cases.
  • Review system logs to understand the execution of scheduled tasks.

References