Practical Examples
Learning Focus
This page contains 27 complete examples, each with the .timer unit, the .service unit, activation commands, and expected output. Every example is copy-paste-ready.
How To Use This Page
- Examples are grouped by schedule frequency — jump to the pattern you need.
- Each example includes
systemd-analyze calendarvalidation where applicable. - Adapt
User=, paths, and scripts to your environment.
Every Minute
1. Health Check (Every Minute)
/etc/systemd/system/health-check.service
[Unit]
Description=Lightweight health check
[Service]
Type=oneshot
ExecStart=/usr/local/bin/health-check.sh
StandardOutput=append:/var/log/health-check.log
StandardError=append:/var/log/health-check.log
/etc/systemd/system/health-check.timer
[Unit]
Description=Run health check every minute
[Timer]
OnCalendar=minutely
Persistent=true
[Install]
WantedBy=timers.target
activate.sh
sudo systemctl daemon-reload
sudo systemctl enable --now health-check.timer
systemctl list-timers health-check.timer --no-pager
expected-output.txt
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon 2026-03-02 00:01:00 UTC 38s left Mon 2026-03-02 00:00:01 UTC 21s ago health-check.timer health-check.service
Every 5–30 Minutes
2. Disk Monitoring (Every 5 Minutes)
/etc/systemd/system/disk-check.service
[Unit]
Description=Disk usage alert
[Service]
Type=oneshot
ExecStart=/usr/local/bin/disk-alert.sh
StandardOutput=append:/var/log/disk-alert.log
StandardError=append:/var/log/disk-alert.log
/etc/systemd/system/disk-check.timer
[Unit]
Description=Check disk usage every 5 minutes
[Timer]
OnCalendar=*:0/5
Persistent=true
[Install]
WantedBy=timers.target
validate.sh
systemd-analyze calendar --iterations=3 '*:0/5'
expected-output.txt
Next elapse: Mon 2026-03-02 00:05:00 UTC
Iter. #2: Mon 2026-03-02 00:10:00 UTC
Iter. #3: Mon 2026-03-02 00:15:00 UTC
3. WordPress Cron Runner (Every 15 Minutes)
Replaces the default wp-cron.php page-visit trigger. Requires define('DISABLE_WP_CRON', true); in wp-config.php.
/etc/systemd/system/wp-cron-runner.service
[Unit]
Description=Run due WordPress cron events
[Service]
Type=oneshot
User=www-data
WorkingDirectory=/var/www/html
ExecStart=/usr/local/bin/wp cron event run --due-now --path=/var/www/html
StandardOutput=append:/var/log/wp-cron.log
StandardError=append:/var/log/wp-cron.log
/etc/systemd/system/wp-cron-runner.timer
[Unit]
Description=Trigger WordPress cron events every 15 minutes
[Timer]
OnCalendar=*:0/15
Persistent=true
[Install]
WantedBy=timers.target
4. CDN Sync (Every 30 Minutes)
/etc/systemd/system/cdn-sync.service
[Unit]
Description=Sync static assets to CDN
[Service]
Type=oneshot
User=www-data
ExecStart=/usr/local/bin/sync-cdn.sh
StandardOutput=append:/var/log/cdn-sync.log
/etc/systemd/system/cdn-sync.timer
[Unit]
Description=Sync CDN every 30 minutes
[Timer]
OnCalendar=*:0/30
Persistent=true
[Install]
WantedBy=timers.target
Hourly
5. Hourly Server Report
/etc/systemd/system/hourly-report.service
[Unit]
Description=Generate hourly server summary
[Service]
Type=oneshot
ExecStart=/usr/local/bin/hourly-report.sh
/etc/systemd/system/hourly-report.timer
[Unit]
Description=Hourly report
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
6. Media Sync to Object Storage (Every 2 Hours)
/etc/systemd/system/media-sync.service
[Unit]
Description=Sync uploads to object storage
[Service]
Type=oneshot
User=www-data
ExecStart=/usr/local/bin/rclone sync /var/www/html/wp-content/uploads remote:wp-uploads
StandardOutput=append:/var/log/media-sync.log
/etc/systemd/system/media-sync.timer
[Unit]
Description=Sync media to object storage every 2 hours
[Timer]
OnCalendar=*-*-* 0/2:00:00
Persistent=true
[Install]
WantedBy=timers.target
7. Cache Flush (Every 6 Hours)
/etc/systemd/system/wp-cache-flush.service
[Unit]
Description=Flush WordPress object cache
[Service]
Type=oneshot
User=www-data
WorkingDirectory=/var/www/html
ExecStart=/usr/local/bin/wp cache flush --path=/var/www/html
StandardOutput=append:/var/log/wp-cache-flush.log
/etc/systemd/system/wp-cache-flush.timer
[Unit]
Description=Flush WordPress object cache every 6 hours
[Timer]
OnCalendar=*-*-* 00/6:00:00
Persistent=true
[Install]
WantedBy=timers.target
Daily
8. WordPress Nightly Backup (2:15 AM)
/etc/systemd/system/wp-backup.service
[Unit]
Description=WordPress nightly backup
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=www-data
Group=www-data
WorkingDirectory=/var/www/html
ExecStart=/usr/bin/flock -n /var/lock/wp-backup.lock /usr/local/bin/wp-backup.sh
StandardOutput=append:/var/log/wp-backup.log
StandardError=append:/var/log/wp-backup.log
RuntimeMaxSec=2h
/etc/systemd/system/wp-backup.timer
[Unit]
Description=Run WordPress backup nightly at 02:15
[Timer]
OnCalendar=02:15
Persistent=true
RandomizedDelaySec=5m
AccuracySec=1m
[Install]
WantedBy=timers.target
activate.sh
sudo systemctl daemon-reload
sudo systemctl enable --now wp-backup.timer
sudo systemctl start wp-backup.service # Test run immediately
journalctl -u wp-backup.service -n 20 --no-pager
expected-output.txt
Mar 02 02:15:07 vps wp-backup.sh[1201]: [2026-03-02T02:15:07] Backup started
Mar 02 02:15:42 vps wp-backup.sh[1201]: [2026-03-02T02:15:42] Database exported: 145M
Mar 02 02:16:10 vps wp-backup.sh[1201]: [2026-03-02T02:16:10] Archive created: wp-backup-2026-03-02.tar.gz
Mar 02 02:16:10 vps wp-backup.sh[1201]: [2026-03-02T02:16:10] Done.
9. Log Rotation (Midnight)
/etc/systemd/system/force-logrotate.service
[Unit]
Description=Force logrotate run
[Service]
Type=oneshot
ExecStart=/usr/sbin/logrotate /etc/logrotate.conf
/etc/systemd/system/force-logrotate.timer
[Unit]
Description=Force logrotate daily at midnight
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
10. Uptime Check (Twice Daily — 9 AM and 9 PM)
/etc/systemd/system/uptime-check.timer
[Unit]
Description=Uptime check twice daily
[Timer]
OnCalendar=09,21:00
Persistent=true
[Install]
WantedBy=timers.target
validate.sh
systemd-analyze calendar --iterations=4 '09,21:00'
expected-output.txt
Next elapse: Mon 2026-03-02 09:00:00 UTC
Iter. #2: Mon 2026-03-02 21:00:00 UTC
Iter. #3: Tue 2026-03-03 09:00:00 UTC
Iter. #4: Tue 2026-03-03 21:00:00 UTC
11. Database Export (Daily at 2:30 AM with Lock)
/etc/systemd/system/wp-db-backup.service
[Unit]
Description=WordPress database export
[Service]
Type=oneshot
User=www-data
ExecStart=/usr/bin/flock -n /var/lock/wp-db-backup.lock /usr/local/bin/wp db export /mnt/backups/wp-db.sql --path=/var/www/html
RuntimeMaxSec=1h
StandardOutput=append:/var/log/wp-db-backup.log
StandardError=append:/var/log/wp-db-backup.log
/etc/systemd/system/wp-db-backup.timer
[Unit]
Description=WordPress DB export daily at 02:30
[Timer]
OnCalendar=02:30
Persistent=true
RandomizedDelaySec=5m
[Install]
WantedBy=timers.target
12. Backup Retention Purge (Daily at 4 AM)
/etc/systemd/system/backup-prune.service
[Unit]
Description=Prune backup files older than 14 days
[Service]
Type=oneshot
ExecStart=/usr/bin/find /mnt/backups -name "*.sql" -mtime +14 -delete
StandardOutput=append:/var/log/backup-prune.log
/etc/systemd/system/backup-prune.timer
[Unit]
Description=Prune old backups daily at 04:00
[Timer]
OnCalendar=04:00
Persistent=true
[Install]
WantedBy=timers.target
13. Peak-Hours Cache Warming (8 AM – 8 PM, Every 10 Minutes)
/etc/systemd/system/cache-warm.service
[Unit]
Description=Warm WordPress page cache
[Service]
Type=oneshot
User=www-data
ExecStart=/usr/local/bin/cache-warm.sh
/etc/systemd/system/cache-warm.timer
[Unit]
Description=Warm cache every 10 minutes during peak hours
[Timer]
OnCalendar=*-*-* 08..20:0/10
Persistent=false
[Install]
WantedBy=timers.target
validate.sh
systemd-analyze calendar --iterations=5 '*-*-* 08..20:0/10'
expected-output.txt
Next elapse: Mon 2026-03-02 08:00:00 UTC
Iter. #2: Mon 2026-03-02 08:10:00 UTC
Iter. #3: Mon 2026-03-02 08:20:00 UTC
Iter. #4: Mon 2026-03-02 08:30:00 UTC
Iter. #5: Mon 2026-03-02 08:40:00 UTC
14. SSL Certificate Renewal (Daily 3 AM with Fleet Jitter)
/etc/systemd/system/certbot-renew.service
[Unit]
Description=Renew TLS certificates with Certbot
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"
StandardOutput=append:/var/log/certbot.log
StandardError=append:/var/log/certbot.log
/etc/systemd/system/certbot-renew.timer
[Unit]
Description=Daily certbot renewal with stable fleet jitter
[Timer]
OnCalendar=03:00
Persistent=true
RandomizedDelaySec=30m
FixedRandomDelay=true
AccuracySec=1m
[Install]
WantedBy=timers.target
Certbot only renews if expiry is within 30 days. The --deploy-hook reloads Nginx only when a renewal happens.
Weekly
15. Business Digest (Weekdays at 6 AM)
/etc/systemd/system/daily-digest.service
[Unit]
Description=Send daily business digest
[Service]
Type=oneshot
ExecStart=/usr/local/bin/send-digest.sh
/etc/systemd/system/daily-digest.timer
[Unit]
Description=Business digest on weekdays at 6 AM
[Timer]
OnCalendar=Mon..Fri 06:00
Persistent=true
[Install]
WantedBy=timers.target
16. Weekly WordPress Cleanup (Monday 3 AM)
/etc/systemd/system/weekly-cleanup.service
[Unit]
Description=Weekly WordPress cleanup and optimization
[Service]
Type=oneshot
User=www-data
ExecStart=/usr/local/bin/wp-weekly-cleanup.sh
StandardOutput=append:/var/log/weekly-cleanup.log
/etc/systemd/system/weekly-cleanup.timer
[Unit]
Description=Weekly cleanup every Monday at 03:00
[Timer]
OnCalendar=Mon 03:00
Persistent=true
RandomizedDelaySec=10m
[Install]
WantedBy=timers.target
Use case: wp db optimize, delete old revisions, clear transients.
17. Saturday Maintenance Window (2 AM)
/etc/systemd/system/maintenance.service
[Unit]
Description=Weekly maintenance (heavier tasks)
[Service]
Type=oneshot
ExecStart=/usr/local/bin/maintenance.sh
RuntimeMaxSec=3h
StandardOutput=append:/var/log/maintenance.log
/etc/systemd/system/maintenance.timer
[Unit]
Description=Run heavy maintenance on Saturday at 02:00
[Timer]
OnCalendar=Sat 02:00
Persistent=true
RandomizedDelaySec=15m
[Install]
WantedBy=timers.target
Use case: Full backup, database vacuum, PHP-FPM restart, plugin update dry-run.
Monthly and Beyond
18. Bimonthly Report (1st and 15th at 4 AM)
/etc/systemd/system/bimonthly-report.timer
[Unit]
Description=Bimonthly report on 1st and 15th
[Timer]
OnCalendar=*-*-01,15 04:00:00
Persistent=true
[Install]
WantedBy=timers.target
validate.sh
systemd-analyze calendar --iterations=4 '*-*-01,15 04:00:00'
expected-output.txt
Next elapse: Sun 2026-03-15 04:00:00 UTC
Iter. #2: Wed 2026-04-01 04:00:00 UTC
Iter. #3: Wed 2026-04-15 04:00:00 UTC
Iter. #4: Fri 2026-05-01 04:00:00 UTC
19. Monthly Report (1st of Month)
/etc/systemd/system/monthly-report.timer
[Unit]
Description=Monthly server report
[Timer]
OnCalendar=monthly
Persistent=true
[Install]
WantedBy=timers.target
20. Quarterly Billing Export
/etc/systemd/system/quarterly-export.timer
[Unit]
Description=Quarterly billing data export
[Timer]
OnCalendar=quarterly
Persistent=true
[Install]
WantedBy=timers.target
validate.sh
systemd-analyze calendar --iterations=4 'quarterly'
expected-output.txt
Next elapse: Wed 2026-04-01 00:00:00 UTC
Iter. #2: Wed 2026-07-01 00:00:00 UTC
Iter. #3: Thu 2026-10-01 00:00:00 UTC
Iter. #4: Fri 2027-01-01 00:00:00 UTC
21. Last Day of Every Month
/etc/systemd/system/month-end-rollup.timer
[Unit]
Description=Month-end data rollup
[Timer]
OnCalendar=*-*~1 00:00:00
Persistent=true
[Install]
WantedBy=timers.target
validate.sh
systemd-analyze calendar --iterations=3 '*-*~1 00:00:00'
expected-output.txt
Next elapse: Tue 2026-03-31 00:00:00 UTC
Iter. #2: Thu 2026-04-30 00:00:00 UTC
Iter. #3: Sun 2026-05-31 00:00:00 UTC
22. First Monday of Each Month
/etc/systemd/system/monthly-first-monday.timer
[Unit]
Description=First Monday of each month at 03:00
[Timer]
OnCalendar=Mon *-*-1..7 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
23. Annual Cleanup (January 1)
/etc/systemd/system/annual-cleanup.timer
[Unit]
Description=Annual cleanup on January 1
[Timer]
OnCalendar=yearly
Persistent=true
[Install]
WantedBy=timers.target
Boot and Monotonic
24. Post-Boot Startup Task (2 Minutes After Boot)
/etc/systemd/system/startup-task.service
[Unit]
Description=One-time startup initialization task
[Service]
Type=oneshot
ExecStart=/usr/local/bin/post-boot-setup.sh
RemainAfterExit=yes
/etc/systemd/system/startup-task.timer
[Unit]
Description=Run startup task 2 minutes after boot
[Timer]
OnBootSec=2min
[Install]
WantedBy=timers.target
25. Boot Then Recurring Hourly (Heartbeat)
/etc/systemd/system/heartbeat.timer
[Unit]
Description=Run heartbeat 30s after boot, then every hour
[Timer]
OnBootSec=30s
OnUnitActiveSec=1h
[Install]
WantedBy=timers.target
26. Cooldown Retry (20 Minutes After Completion)
/etc/systemd/system/retry-worker.timer
[Unit]
Description=Retry worker 20 minutes after each run completes
[Timer]
OnUnitInactiveSec=20m
[Install]
WantedBy=timers.target
"Next run starts 20 minutes after the previous run finished, not 20 minutes after it started."
Advanced
27. User-Level Timer (No Root Required)
~/.config/systemd/user/personal-backup.service
[Unit]
Description=Personal file backup
[Service]
Type=oneshot
ExecStart=%h/bin/backup-home.sh
StandardOutput=append:%h/logs/backup.log
~/.config/systemd/user/personal-backup.timer
[Unit]
Description=Personal backup every 6 hours
[Timer]
OnCalendar=*-*-* 00/6:00:00
Persistent=true
[Install]
WantedBy=default.target
activate-user-timer.sh
systemctl --user daemon-reload
systemctl --user enable --now personal-backup.timer
sudo loginctl enable-linger "$USER"
systemctl --user list-timers --no-pager
Example Quick Reference
| # | Pattern | Schedule | Key Feature |
|---|---|---|---|
| 1 | Health check | minutely | High-frequency polling |
| 2 | Disk alert | *:0/5 | Step-based interval |
| 3 | WP cron | *:0/15 | Replaces wp-cron.php |
| 4 | CDN sync | *:0/30 | Periodic sync |
| 5 | Hourly report | hourly | Keyword shortcut |
| 6 | Media sync | 0/2:00:00 | Multi-hour interval |
| 7 | Cache flush | 00/6:00:00 | 4x daily |
| 8 | WP backup | 02:15 | flock + RuntimeMaxSec |
| 9 | Log rotation | daily | Keyword shortcut |
| 10 | Uptime check | 09,21:00 | List operator |
| 11 | DB export | 02:30 | flock + jitter |
| 12 | Backup purge | 04:00 | find + delete retention |
| 13 | Cache warming | 08..20:0/10 | Range + step |
| 14 | Certbot | 03:00 | FixedRandomDelay fleet |
| 15 | Business digest | Mon..Fri 06:00 | Range operator |
| 16 | Weekly cleanup | Mon 03:00 | WP optimize |
| 17 | Maintenance | Sat 02:00 | Heavy weekend window |
| 18 | Bimonthly | *-*-01,15 04:00 | Day list |
| 19 | Monthly report | monthly | Keyword |
| 20 | Quarterly | quarterly | Keyword |
| 21 | Month-end | *-*~1 00:00 | Tilde (last day) |
| 22 | First Monday | Mon *-*-1..7 03:00 | Range + day-of-week |
| 23 | Annual | yearly | Keyword |
| 24 | Post-boot | OnBootSec=2min | One-shot startup |
| 25 | Boot+recurring | OnBootSec=30s + OnUnitActiveSec=1h | Combined |
| 26 | Cooldown retry | OnUnitInactiveSec=20m | Gap after completion |
| 27 | User timer | 00/6:00:00 + linger | No root, %h specifier |
What's Next
- Production Patterns — hardening, flock overlap prevention, Persistent, jitter, and fleet safety.