Linux

Systemd Timers: A Flexible Cron Replacement for Automation in Linux

In this guide, you'll learn how to use systemd timers—a modern and powerful task scheduling mechanism in Linux that offers more features than classic cron. We'll cover unit creation, management via systemctl, and troubleshooting common issues.

Updated at February 16, 2026
15-30 minutes
Medium
FixPedia Team
Применимо к:systemd 235+ (all modern distributions: Ubuntu 18.04+, Debian 9+, CentOS 7+, Fedora 25+)

Introduction / Why This Is Needed

Systemd timers are a modern job scheduling mechanism in systems using systemd (virtually all current Linux distributions). They replace the classic cron, offering tighter integration with the init system, advanced scheduling capabilities, and a unified event log (journalctl). With timers, you can automate backups, log cleanup, update checks, or run any script on a schedule, with a delay after boot, or even in response to other system events.

After completing this guide, you will be able to create reliable and easily manageable jobs that correctly handle missed runs (e.g., if the computer was off) and provide detailed information about their operations.

Requirements / Preparation

  1. System with systemd: Ensure your distribution uses systemd (check echo $INIT_SYSTEM or ps -p 1 -o comm=).
  2. Superuser (root) privileges: Creating system units in /etc/systemd/system/ and managing them requires administrator rights. For user-specific timers (without sudo), use ~/.config/systemd/user/.
  3. Basic understanding of systemd: It is helpful to know what unit files are and the systemctl command.
  4. Text editor: For example, nano, vim, or vi.

Step 1: Create the Service File (.service)

A timer does not execute commands directly. It activates a service file (.service), which contains the instructions for running your task. Let's start with that.

We'll create a simple service to back up the home directory. Save this config as /etc/systemd/system/home-backup.service:

[Unit]
Description=Home directory backup
# Run the service only if the network is available (optional)
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
# The command to execute. Example using tar with compression.
ExecStart=/bin/tar -czf /var/backups/home_$(date +\%Y-\%m-\%d).tar.gz /home
# Indicates the job runs once per timer activation
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Key points:

  • Type=oneshot: The service process terminates after ExecStart completes. Used for one-off tasks.
  • ExecStart: The main command. Note the escaping of % in date (requires \%).
  • RemainAfterExit=yes: Allows the service to be considered active after the command finishes. Useful for status monitoring.
  • To run multiple commands, use a script and point ExecStart to it, or use ExecStartPre/ExecStartPost.

Step 2: Create the Timer File (.timer)

Now create the timer file that will trigger our service on a schedule. Save it as /etc/systemd/system/home-backup.timer:

[Unit]
Description=Timer for daily home directory backup

[Timer]
# Schedule: every day at 02:30
OnCalendar=*-*-* 02:30:00
# If the job was missed (computer was off), run it on the next boot
Persistent=true
# The service to activate
Unit=home-backup.service

[Install]
WantedBy=timers.target

Key points:

  • OnCalendar=*-*-* 02:30:00: Flexible calendar syntax. * means "any value." Here: any year, any month, any day at 02:30.
    • Examples: Mon *-*-* 09:00:00 (every Monday at 9 AM), *-*-1 00:00:00 (the first day of every month).
  • Persistent=true: A critically important option! If the computer is off at the scheduled time, systemd will run the job immediately upon the next system boot.
  • Unit=home-backup.service: Explicitly specifies which service to start. If the service filename matches the timer name (e.g., home-backup.timer and home-backup.service), this parameter can be omitted.

Step 3: Reload systemd Configuration

After creating both files, you must inform systemd of their existence. Run:

sudo systemctl daemon-reload

This command forces systemd to reread all configuration files. Without it, new timers and services will not be visible to the system.

Step 4: Enable and Start the Timer

Now you need to enable the timer (so it starts automatically at boot) and optionally start it immediately for testing.

# 1. Enable the timer to start automatically at boot
sudo systemctl enable home-backup.timer

# 2. Start the timer immediately (for testing)
sudo systemctl start home-backup.timer

# 3. Check the status
sudo systemctl status home-backup.timer

You should see an active (active (waiting)) timer and the next run time (Next elapse).

Step 5: Monitoring and Management

View all active timers

To see a list of all configured timers and their next activation times, use:

systemctl list-timers

This command displays a table with the timer name, next run time, last run time, and the unit it activates.

View logs

Everything your service outputs (including errors) goes into the systemd journal. Use journalctl to view it:

# Logs for the specific timer and its associated service
sudo journalctl -u home-backup.timer -u home-backup.service -f

# Logs from the last day
sudo journalctl -u home-backup.service --since "1 day ago"

Stopping and disabling

  • Stop the current run (if it's in progress): sudo systemctl stop home-backup.timer
  • Stop and disable autostart: sudo systemctl disable --now home-backup.timer

Step 6: Advanced Features and Examples

Run with a delay after boot

If a task should run not on a calendar schedule, but after a certain time post-boot (e.g., to allow network services to start), use OnBootSec:

[Timer]
OnBootSec=15min
Unit=home-backup.service

This runs the service 15 minutes after boot. You can combine: OnBootSec=5min and OnUnitActiveSec=1h to run after 5 minutes post-boot and then every hour.

Periodic run (interval)

For intervals not tied to a calendar (e.g., "every 30 minutes"), use OnUnitActiveSec:

[Timer]
OnUnitActiveSec=30min
Unit=home-backup.service

This means: run the service every 30 minutes after its last successful run.

Randomized (staggered) execution

To avoid a "thundering herd" when many timers fire simultaneously on multiple machines (e.g., for updates), add RandomizedDelaySec:

[Timer]
OnCalendar=daily
RandomizedDelaySec=1h

The job will run at a random moment within one hour after midnight.

Verifying the Result

  1. Ensure the timer is active: systemctl is-active home-backup.timer should return active.
  2. Check the schedule: systemctl list-timers | grep home-backup will show the next run time.
  3. Wait for activation (or manually trigger it with sudo systemctl start home-backup.timer) and check:
    • The backup file: ls -lh /var/backups/
    • Service status: systemctl status home-backup.service
    • Journal: sudo journalctl -u home-backup.service --no-pager -n 20

If the backup was created and there are no errors in the logs—everything is working.

Common Issues

Timer doesn't run on schedule

  • Check OnCalendar syntax. Use systemd-analyze calendar '*-*-* 02:30:00' to validate.
  • Ensure Persistent=true is set if the computer might be off at the scheduled time.
  • Check for conflicts with cron. Systemd and cron are independent. If the job already exists in cron, disable it to avoid duplicate runs.

Service started by timer exits with an error

  • Check the service logs with journalctl -u <service>.service. The error is almost always in the ExecStart command (wrong path, missing permissions, insufficient space).
  • Verify access permissions to the script/command and target directories/files. System services often require root.
  • Confirm Type=oneshot matches your task. If the command starts a daemon, you may need Type=forking or Type=notify.

Timer not visible in systemctl list-timers

  • Did you run daemon-reload after creating the files?
  • Are the files named and located correctly? For system units: /etc/systemd/system/<name>.timer. For user units: ~/.config/systemd/user/.
  • Is the timer enabled? sudo systemctl enable <name>.timer (for system) or systemctl --user enable <name>.timer (for user).
  • Check if the timer is already active: systemctl status <name>.timer. If it shows active (waiting), it's working. If inactive (dead), it may need to be started (start).

F.A.Q.

What is the main advantage of a systemd timer over cron?
How do I check if my timer is working?
Can I run a timer only when the network is available?

Hints

Understanding the structure: two units
Creating the service file
Creating the timer file
Reloading systemd configuration
Activating and starting the timer
Monitoring and debugging
FixPedia

Free encyclopedia for fixing errors. Step-by-step guides for Windows, Linux, macOS and more.

© 2026 FixPedia. All materials are available for free.

Made with for the community