How to Create Systemd Timers for Automated Maintenance on Fedora

How to Create Systemd Timers for Automated Maintenance on Fedora

If you’ve ever wanted to run a cleanup task automatically on your Fedora system without having to remember to do it manually, systemd timers are your answer. They’re like cron jobs, but more powerful and easier to manage. I’ll walk you through what they are, how to create them, and why they’re actually really useful.

What is a Systemd Timer?

A systemd timer is a way to schedule tasks on Linux. Instead of using the old cron scheduler, timers work with systemd services. A timer tells systemd “run this task at this time”, and a service file tells systemd “here’s what to actually run”.

Think of it like setting an alarm on your phone. The alarm (timer) goes off at a certain time, and when it does, it triggers an action (service). The action might be “clean up old files” or “update your system” or anything else you want automated.

Why Use Timers Instead of Cron?

Systemd timers have several advantages over traditional cron:

  • They integrate with systemd, so you can see what’s running with standard systemd commands
  • They’re easier to debug if something goes wrong
  • They can depend on other services and units (wait until network is up, for example)
  • They log to the journal, which is centralized and searchable
  • They’re more flexible about when they run (second-level precision, not just minutes)
  • If your system is shut down when a timer should run, it can catch up automatically
  • Multiple timers can run on different timezones at the same time
  • They can be triggered by system events, not just clock time

The main disadvantage is they require more configuration than a simple cron job (you need both a .timer file and a .service file), and they have some gotchas if you don’t know about them.

The Two Files You Need

To set up a timer, you need two files in /etc/systemd/system/:

  1. A service file (ends in .service) – tells systemd what to run
  2. A timer file (ends in .timer) – tells systemd when to run it

Let me show you a real example.

Example: Auto-Clean Your Flatpak Runtimes

Flatpak can accumulate unused runtimes and data over time. This simple timer cleans that up automatically. Here’s the service file.

Step 1: Create the Service File

Save this as /etc/systemd/system/linuxtweaks-flatpak-cleanup.service:

[Unit]
Description=LinuxTweaks clean up unused Flatpak runtimes
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/flatpak uninstall --system --unused -y
StandardOutput=journal
StandardError=journal

What does each part do?

  • [Unit] – General information about the task
  • Description – Human readable name for what this does
  • After=network-online.target – Wait until network is available before running
  • [Service] – The actual command to run
  • Type=oneshot – Run once and stop (don’t keep running)
  • ExecStart – The actual command to execute
  • StandardOutput=journal and StandardError=journal – Send output to systemd journal so you can see what happened

Step 2: Create the Timer File

Save this as /etc/systemd/system/linuxtweaks-flatpak-cleanup.timer:

[Unit]
Description=LinuxTweaks run Flatpak cleanup twice daily

[Timer]
OnBootSec=10m
OnUnitActiveSec=12h
Persistent=true

[Install]
WantedBy=timers.target

What does this mean?

  • OnBootSec=10m – Run 10 minutes after the system boots
  • OnUnitActiveSec=12h – Then run again every 12 hours after it last ran
  • Persistent=true – If the system was off when the timer should have run, run it next time it boots
  • WantedBy=timers.target – Enable this timer by default

How to Deploy It

Once you’ve created both files, tell systemd to reload and start the timer:

sudo systemctl daemon-reload
sudo systemctl enable linuxtweaks-flatpak-cleanup.timer
sudo systemctl start linux-tweaks-flatpak-cleanup.timer

That’s it. Now it will run automatically.

How to Check If It Works

See if your timer is active:

systemctl list-timers

You’ll see a table with all active timers, including when they last ran and when they’ll run next.

Another Example: Clean Up Podman

If you use Podman containers, they can leave behind stopped containers and unused images. Here’s a timer to clean that up daily.

Service File: /etc/systemd/system/linuxtweaks-podman-prune.service

[Unit]
Description=LinuxTweaks clean up unused Podman images and containers
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/podman system prune -af
StandardOutput=journal
StandardError=journal

Timer File: /etc/systemd/system/linuxtweaks-podman-prune.timer

[Unit]
Description=Run Podman cleanup daily

[Timer]
OnBootSec=15m
OnUnitActiveSec=1d
Persistent=true

[Install]
WantedBy=timers.target

Deploy the same way:

sudo systemctl daemon-reload
sudo systemctl enable linuxtweaks-podman-prune.timer
sudo systemctl start linuxtweaks-podman-prune.timer

Important: AccuracySec and Timing Precision

Here’s something most people don’t realize about systemd timers: by default, they do NOT run at the exact time you specify. They run within a window of plus 60 seconds by default.

This is intentional. The default of 1-minute variance exists to reduce CPU wake-ups and save power. But if you want precise timing (like running at exactly 14:30:00), you need to set:

AccuracySec=1s

This changes the tolerance from 1 minute to 1 second. If you’re running critical cleanup tasks or need exact timing, add this to your timer section. For most maintenance jobs, the default is fine, but it’s worth knowing.

Useful Timer Schedules

Here are some common patterns you can use in your timer files:

  • OnUnitActiveSec=1h – Every hour
  • OnUnitActiveSec=1d – Every day
  • OnUnitActiveSec=1w – Every week
  • OnBootSec=5m – 5 minutes after boot
  • OnCalendar=daily – Once per day at midnight
  • OnCalendar=Mon *-*-* 03:00:00 – Every Monday at 3 AM
  • OnCalendar=*:0/5:0 – Every 5 minutes
  • OnCalendar=0/2:0:0 – Every 2 hours
  • OnCalendar=Mon..Fri 09:00:00 – Weekdays at 9 AM

Catching Up on Missed Executions

If your system was shut down when a timer should have run, you can configure it to catch up automatically. Add this to your timer file:

Persistent=true

With this setting, if a scheduled time passes while the system is off, the timer will run once when the system boots. Without it, the timer just skips the missed runs. For maintenance tasks, setting Persistent=true is usually a good idea.

How to View Logs

To see what your timer did the last time it ran:

journalctl -u linuxtweaks-flatpak-cleanup.service

This shows you the output from the service. If something went wrong, you’ll see the error here.

To see all timer activity:

journalctl -u linuxtweaks-flatpak-cleanup.timer

Debugging Timers

If a timer isn’t working, these commands help diagnose the problem:

Check syntax errors:

systemd-analyze verify /etc/systemd/system/linuxtweaks-flatpak-cleanup.timer

Systemd silently ignores typos in config files, so this command catches mistakes like OnCalndar= instead of OnCalendar=.

See all active timers:

systemctl list-timers

This shows a table of all running timers, when they last executed, and when they’ll run next.

See all timers (including disabled ones):

systemctl list-timers --all

Test your OnCalendar syntax:

systemd-analyze calendar "Mon..Fri 09:00:00"

This shows you how systemd interprets your schedule and when it will run next.

Disable or Remove a Timer

If you want to stop a timer:

sudo systemctl stop linuxtweaks-flatpak-cleanup.timer
sudo systemctl disable linuxtweaks-flatpak-cleanup.timer

And delete the files:

sudo rm /etc/systemd/system/linuxtweaks-flatpak-cleanup.timer
sudo rm /etc/systemd/system/linuxtweaks-flatpak-cleanup.service
sudo systemctl daemon-reload

Why This Matters for Your System

Timers keep your system healthy without you having to think about it. Over time, package managers, containers, and Flatpak all leave behind unused files and data. Running cleanup automatically means:

  • Your disk stays cleaner
  • Your system stays organized
  • You never forget to do maintenance
  • Everything runs in the background with no interaction needed

Once you set it up once, it just works. No cron syntax to remember, no cronjobs file to edit. Just systemd doing its job.

Running Timers as a Regular User

You don’t have to be root to use timers. Regular users can create timers too. Put your timer and service files in ~/.config/systemd/user/ instead of /etc/systemd/system/, then enable them with --user:

mkdir -p ~/.config/systemd/user/

# Create your timer and service files there
systemctl --user daemon-reload
systemctl --user enable my-timer.timer
systemctl --user start my-timer.timer

Important: User timers only run while you’re logged in. To keep them running even after you log out, run:

loginctl enable-linger $USER

This is useful if you want personal backups or cleanup scripts running automatically without needing root access.

When NOT to Use Timers

For tasks that need to run very frequently (every few seconds), timers aren’t ideal. Instead, write a simple daemon script with a loop and sleep. For example:

#!/bin/bash
while true; do
    # Do your work here
    echo "Running task..."
    sleep 5
done

Then create a systemd service (not a timer) that runs this daemon. This is much simpler than trying to set up a timer that runs multiple times per second.

Summary

To create a systemd timer:

  1. Create a service file with ExecStart=/path/to/command
  2. Create a timer file with scheduling information
  3. Run sudo systemctl daemon-reload and sudo systemctl enable --now timer-name.timer
  4. Check it with systemctl list-timers
  5. View logs with journalctl -u service-name.service
  6. Verify syntax with systemd-analyze verify /etc/systemd/system/timer-name.timer

Start with simple cleanup tasks like the Flatpak example above, and once you’re comfortable, you can automate almost anything: system updates, backups, log rotation, or custom scripts.

Key things to remember:

  • Timers don’t run at exact times by default (add AccuracySec=1s if you need precision)
  • Add Persistent=true to catch up on missed runs after reboots
  • Use systemctl list-timers to see what you’ve set up
  • Use systemd-analyze verify to catch typos in your config files

The nice thing is once it’s set up, you can forget about it. Your system stays clean automatically.

Leave a Reply

Your email address will not be published. Required fields are marked *

*