Table of Contents

Move from Cron to Systemd Timer

Summary: This wiki page shows how to schedule your tasks and scripts using Systemd Timer instead of cron.
Date: 19 June 2026

I manage a few linux hosts, and after upgrading one of them I found that cron was no longer included in the default installed packaged. I was shocked after finding this out, and then relieved after I found out that cron is now reaplced by systemd timers, a much more flexible and reliable way to schedule tasks and scripts. Below I'll show you how to create a Systemd timer for a backup script.

The Service

First let's focus on creating the service, as that's the thing Systemd manages. This will immediately show some of the benefits:

backup.service
[Unit]
Description=Daily Backup Service - Database and Filestore
After=network.target docker.service
Wants=network.target
Requires=docker.service
 
[Service]
Type=oneshot
User=root
Group=root
ExecStart=/usr/bin/bash /data/scripts/backup.sh
WorkingDirectory=/data/scripts
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Environment=HOME=/root
# Timeout after 4 hours (backup can take a while)
TimeoutStartSec=14400
# Don't restart on failure
Restart=no
# Make sure it waits for docker containers to be ready
ExecStartPre=/bin/sleep 30

Immediately we see some interesting stuff. Mu backup script needs to backup some stuff inside docker containers, we we've set dependencies on the network and docker. We also configured stuff like timeouts, restart behavior, the user and group and more. Really nice.

The Timer

Now we need the timer, because that will determine the schedule:

backup.timer
[Unit]
Description=Run backup service daily at 22:22 with random delay
Requires=backup.service
 
[Timer]
# Run daily at 22:22
OnCalendar=*-*-* 22:22:00
# Add random delay up to 5 minutes (300 seconds)
RandomizedDelaySec=300
# Catch up on missed runs if system was down
Persistent=true
# Don't run if system is on battery (if applicable)
WakeSystem=false
 
[Install]
WantedBy=timers.target

Again, we see some interesting stuff. Not only did we set a schedule, we've also added a randomized delay, which is useful if you have multiple systems starting the backup at the same time and we've set to catch up on the task if the system was down.

Installation

To be able to use the timer we need to create the correct file and set the permissions correctly:

# Copy service and timer files to systemd directory
sudo cp backup.service /etc/systemd/system/
sudo cp backup.timer /etc/systemd/system/
 
# Set proper permissions
sudo chmod 644 /etc/systemd/system/backup.service
sudo chmod 644 /etc/systemd/system/backup.timer

Now we can enable and start the timer:

# Reload systemd to recognize new files
sudo systemctl daemon-reload
 
# Enable timer to start on boot
sudo systemctl enable backup.timer
 
# Start the timer now
sudo systemctl start backup.timer

Verify Installation

After installing we can verify the installation by checking the status, the schedule for the timer and check the logs:

# Check timer status
sudo systemctl status backup.timer
 
# List all timers to see next run time
systemctl list-timers backup.timer --all
 
# View timer logs
sudo journalctl -u backup.timer -f

Did you notice something? The logs are now part of the journalctl logs. So you don't have to worry about logs anymore.

Manual Execution

We can also start the timer manually. Convenient for testing the service and for testing the script:

# Run backup manually (for testing)
sudo systemctl start backup.service
 
# Check service status
sudo systemctl status backup.service
 
# View service logs
sudo journalctl -u backup.service -f

Timer Management

In case it's needed it's also possible of course to disable or stop the timer and then start it again:

# Start timer
sudo systemctl start backup.timer
 
# Stop timer
sudo systemctl stop backup.timer
 
# Restart timer
sudo systemctl restart backup.timer
 
# Disable timer (prevent auto-start on boot)
sudo systemctl disable backup.timer
 
# Check when timer will run next
systemctl list-timers backup.timer

Log Monitoring

I already mentioned that the normal journalctl logging method is being used, so, if needed, here are some examples on how to check the logs, depending on your needs:

# View recent backup logs
sudo journalctl -u backup.service -n 50
 
# Follow logs in real-time
sudo journalctl -u backup.service -f
 
# View logs for specific date
sudo journalctl -u backup.service --since "2024-04-26" --until "2024-04-27"
 
# View all timer-related logs
sudo journalctl -u backup.timer -u backup.service

This wiki has been made possible by: