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/:
- A service file (ends in .service) – tells systemd what to run
- 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 taskDescription– Human readable name for what this doesAfter=network-online.target– Wait until network is available before running[Service]– The actual command to runType=oneshot– Run once and stop (don’t keep running)ExecStart– The actual command to executeStandardOutput=journalandStandardError=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 bootsOnUnitActiveSec=12h– Then run again every 12 hours after it last ranPersistent=true– If the system was off when the timer should have run, run it next time it bootsWantedBy=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 hourOnUnitActiveSec=1d– Every dayOnUnitActiveSec=1w– Every weekOnBootSec=5m– 5 minutes after bootOnCalendar=daily– Once per day at midnightOnCalendar=Mon *-*-* 03:00:00– Every Monday at 3 AMOnCalendar=*:0/5:0– Every 5 minutesOnCalendar=0/2:0:0– Every 2 hoursOnCalendar=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:
- Create a service file with
ExecStart=/path/to/command - Create a timer file with scheduling information
- Run
sudo systemctl daemon-reloadandsudo systemctl enable --now timer-name.timer - Check it with
systemctl list-timers - View logs with
journalctl -u service-name.service - 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=1sif you need precision) - Add
Persistent=trueto catch up on missed runs after reboots - Use
systemctl list-timersto see what you’ve set up - Use
systemd-analyze verifyto 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