Cron and Systemd Timers: Schedule Tasks the Linux Way
Have you ever wanted your computer to automatically run a task at a specific time? Maybe backup your files every night, send yourself a reminder email on Mondays, or clean up temporary files every week? In Linux, you can automate these tasks using two powerful tools: Cron and Systemd Timers.
Think of these tools as your personal assistant that never forgets to do repetitive tasks for you!
What is Task Scheduling?
Task scheduling is simply telling your computer to run a program or command at specific times automatically. Instead of manually running a backup script every day, you can schedule it to run at 2 AM when you’re sleeping.
Common examples include:
- Backing up important files daily
- Cleaning temporary files weekly
- Sending system reports monthly
- Updating software automatically
- Restarting services at specific intervals
Now let’s explore the two main ways to schedule tasks in Linux.
Part 1: Cron - The Traditional Way
Cron (short for “chronograph”) has been the go-to task scheduler in Unix-like systems for decades. It’s like having a very reliable alarm clock that can run any command you want.
How Cron Works
Cron runs as a background service (called a “daemon”) that checks every minute if there are any scheduled tasks to execute. These scheduled tasks are stored in files called “crontabs” (cron tables).
Understanding Cron Syntax
Cron uses a specific format to define when tasks should run. It might look confusing at first, but it follows a simple pattern:
Each *
means “every” - so * * * * *
means “every minute of every hour of every day.”
Cron Examples
Let’s look at some practical examples:
Run a backup script every day at 2:30 AM:
|
|
Send a report every Monday at 9 AM:
|
|
Clean temporary files every Sunday at midnight:
|
|
Check disk space every 30 minutes:
|
|
Working with Cron
View your current cron jobs:
|
|
Edit your cron jobs:
|
|
This opens a text editor where you can add, modify, or remove scheduled tasks.
Remove all your cron jobs:
|
|
Cron Shortcuts
Cron provides some handy shortcuts for common schedules:
@yearly
or@annually
- Run once a year (same as0 0 1 1 *
)@monthly
- Run once a month (same as0 0 1 * *
)@weekly
- Run once a week (same as0 0 * * 0
)@daily
or@midnight
- Run once a day (same as0 0 * * *
)@hourly
- Run once an hour (same as0 * * * *
)@reboot
- Run at system startup
Example using shortcuts:
Your First Cron Job - A Complete Example
Let’s create your first scheduled task using cron:
Step 1: Create a simple script
Step 2: Test the script manually
Step 3: Schedule it with cron
Step 4: Wait and check results After a minute or two, check the log file:
|
|
You should see multiple timestamps showing when the script ran!
Step 5: Remove the test job
Now you understand how cron works! Let’s move on to the modern alternative.
Part 2: Systemd Timers - The Modern Alternative
Systemd is a newer system management tool that’s now standard on most Linux distributions. Systemd timers are the modern replacement for cron jobs, offering more features and better integration with the system.
Why Use Systemd Timers?
While cron is simple and works well, systemd timers offer several advantages:
- Better logging: Easier to see what happened and debug issues
- Dependencies: Can wait for other services to start first
- Resource control: Can limit CPU, memory usage
- More flexible scheduling: Can handle complex timing requirements
- System integration: Works seamlessly with other systemd services
How Systemd Timers Work
This is the key difference from cron: systemd timers require TWO separate files that work together:
- Service file (
.service
) - Defines WHAT to run - Timer file (
.timer
) - Defines WHEN to run it
Think of it this way: the service file is like writing down instructions for a task, and the timer file is like setting an alarm clock to remind you to do that task.
Creating Your First Systemd Timer
Let’s create a complete example step by step. We’ll make a backup timer that runs daily.
Step 1: Create the Service File
The service file defines what command to run. Let’s create backup.service
:
First, create the file:
|
|
Add this content:
|
|
Understanding the Service File:
[Unit] Section - Basic Information
Description=
- Human-readable description of what this service doesAfter=network.target
- Wait for network to be available before running
[Service] Section - What Actually Runs
Type=oneshot
- This task runs once and then finishes (perfect for scheduled tasks)User=myuser
- Run as your user (replace “myuser” with your actual username)WorkingDirectory=
- Set the working directory for the scriptEnvironment=PATH=
- Set environment variablesExecStart=
- The actual command to run (must be full path)StandardOutput=journal
- Send output to systemd’s logging systemStandardError=journal
- Send errors to systemd’s logging system
[Install] Section - System Integration
WantedBy=multi-user.target
- When this service should be available
Step 2: Create the Timer File
Now we create the timer file that tells systemd when to run our service. Let’s create backup.timer
:
Create the timer file:
|
|
Add this content:
Understanding the Timer File:
[Unit] Section
Description=
- What this timer doesRequires=backup.service
- This timer needs the backup service to exist
[Timer] Section - The Scheduling
OnCalendar=daily
- Run every day at midnightPersistent=true
- If the system was off when the timer should have run, run it when the system starts
[Install] Section
WantedBy=timers.target
- This timer should start with the timer system
Step 3: Install the Timer
Now we need to install both files and activate the timer:
Copy files to systemd directory:
Reload systemd to recognize new files:
|
|
Enable and start the timer:
Step 4: Verify Everything Works
Check timer status:
|
|
List all active timers:
|
|
Test the service manually:
View logs:
Systemd Timer Schedule Formats
Systemd uses a more human-readable format for scheduling than cron:
Common Examples:
OnCalendar=daily
- Every day at midnightOnCalendar=weekly
- Every Sunday at midnightOnCalendar=monthly
- First day of every month at midnightOnCalendar=*-*-* 02:30:00
- Every day at 2:30 AMOnCalendar=Mon *-*-* 09:00:00
- Every Monday at 9 AMOnCalendar=*-*-01 00:00:00
- First day of every month
Managing Systemd Timers
List all timers:
|
|
Check specific timer status:
|
|
View timer logs:
Stop a timer:
|
|
Disable a timer:
|
|
Remove timer files:
Part 3: Cron vs Systemd Timers - Which Should You Choose?
Choose Cron if:
- You want something simple and quick to set up
- You’re working on older systems
- You need basic scheduling without complex requirements
- You’re comfortable with the traditional cron syntax
- You want something that works the same way across different Unix systems
Choose Systemd Timers if:
- You want better logging and debugging capabilities
- You need dependencies (wait for network, other services)
- You want resource control (CPU/memory limits)
- You’re building more complex automation workflows
- You prefer modern, well-integrated tools
- You’re working primarily on modern Linux distributions
Part 4: Practical Tips for Beginners
1. Start Simple
Begin with basic tasks like creating log files or simple backups before moving to complex scripts.
2. Test Your Commands First
Always test your commands manually before scheduling them:
3. Use Full Paths
Always use complete file paths in your scheduled tasks:
4. Handle Output and Errors
Redirect output to files so you can check if things worked:
For Cron:
For Systemd: (Output automatically goes to journal)
5. Set Environment Variables
Scheduled tasks run with minimal environment. Set important variables:
For Cron:
For Systemd: (Use Environment= in service file)
Part 5: Common Gotchas to Avoid
Environment Differences
Scheduled tasks run in a different environment than your interactive shell. Commands that work in your terminal might fail when scheduled because:
- Different PATH variable
- Missing environment variables
- Different working directory
Permissions
Make sure:
- Your scripts are executable (
chmod +x script.sh
) - You have permission to read/write files the script uses
- System-wide timers may need sudo privileges
Time Zones
Both cron and systemd use the system’s local time zone. If you change time zones or deal with daylight saving time, be aware this might affect your schedules.
Testing is Crucial
Always test your scheduled tasks manually before setting them to run automatically. This catches most problems early.
Conclusion
Task scheduling is a powerful way to automate repetitive tasks in Linux. Whether you choose the traditional cron or modern systemd timers, both tools can help you create a more efficient and automated system.
Quick Summary:
- Cron: Simple, traditional, works everywhere, good for basic scheduling
- Systemd Timers: Modern, powerful, better logging, good for complex scenarios
Start with simple tasks, test everything manually first, and gradually build more complex automation as you become comfortable with the tools. Remember, the goal is to make your life easier by letting the computer handle routine tasks while you focus on more important things.
The key to success is starting small, testing thoroughly, and building up your automation skills step by step. Happy scheduling!