Menu
Szybki wybór
Hosting Domeny VPS SSL Kalkulator Porównania FAQ
Aktywne kody
Wszystkie kody rabatowe

systemd timer vs cron: które narzędzie wybrać?

Opublikowano: 9 kwietnia 2026 · Kategoria: DevOps

Cron jest z nami od 1975 roku i przez dekady był jedynym rozsądnym sposobem na uruchamianie zadań cyklicznych w Linuksie. Od czasów systemd (2010) mamy jednak nową alternatywę — systemd timer — która rozwiązuje wiele bolączek crona: brak logowania, brak catchup po downtime, prymitywny harmonogram, brak zależności. W tym artykule porównamy oba narzędzia na konkretnych przykładach i pokażemy, kiedy warto przenieść crony do systemd timerów.

Jak działa cron

Cron to demon, który co minutę sprawdza plik /etc/crontab oraz crontaby użytkowników i uruchamia zadania, których czas nadszedł. Składnia to pięć pól (minuta, godzina, dzień miesiąca, miesiąc, dzień tygodnia) i polecenie do wykonania. Prosta, znana od pokoleń.

# Edytuj crontab uzytkownika
crontab -e

# Przyklad crontab: backup codziennie o 3:00
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# Co 15 minut: sprawdzenie zdrowia
*/15 * * * * /usr/local/bin/healthcheck.sh

# W kazdy poniedzialek o 6:30
30 6 * * 1 /usr/local/bin/weekly-report.sh

# Co godzine w dniach roboczych (pon-pt)
0 * * * 1-5 /usr/local/bin/sync.sh

# Listuj aktywne crony
crontab -l

# Loguj wszystkie crony (wlacz w /etc/rsyslog.d/50-default.conf)
# odkomentuj: cron.* /var/log/cron.log

Problem z cronem jest taki, że nie loguje domyślnie niczego — jeśli twój skrypt wypluje błąd na stderr, cron wyśle mail (o ile MTA jest skonfigurowany), a jeśli nie — błąd znika w próżni. Dlatego konwencjonalnie przekierowuje się stdout i stderr do pliku logu ręcznie. Kolejny problem: gdy serwer jest offline w momencie zaplanowanego uruchomienia, cron pomija to zadanie i czeka na kolejne wystąpienie.

Anatomia systemd timer

systemd timer składa się z dwóch plików: .service (co uruchomić) i .timer (kiedy uruchomić). Oba żyją w /etc/systemd/system/ lub ~/.config/systemd/user/ dla timerów użytkownika.

# /etc/systemd/system/backup.service
[Unit]
Description=Daily backup job
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
User=backup
Group=backup
ExecStart=/usr/local/bin/backup.sh
StandardOutput=journal
StandardError=journal
Nice=10
IOSchedulingClass=idle

# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily at 3am
Requires=backup.service

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
RandomizedDelaySec=300
Unit=backup.service

[Install]
WantedBy=timers.target

OnCalendar to najmocniejsza broń systemd timerów — obsługuje składnię dużo bogatszą niż cron. Możesz użyć wyrażeń typu Mon..Fri 09:00, *-*-01 12:00 (każdy pierwszy dzień miesiąca) albo *:0/15 (co 15 minut). Dodatkowo są predykaty: daily, weekly, monthly, hourly, yearly.

Zarządzanie timerami

Po utworzeniu plików musisz przeładować systemd i włączyć timer. systemd traktuje timery jak każdą inną jednostkę — enable, start, stop, status.

# Przeladuj konfiguracje systemd
sudo systemctl daemon-reload

# Wlacz timer (start po boot)
sudo systemctl enable backup.timer

# Uruchom timer teraz
sudo systemctl start backup.timer

# Status timera (kiedy uruchomi sie nastepnym razem)
systemctl status backup.timer

# Lista wszystkich timerow z nastepnym uruchomieniem
systemctl list-timers

# Lista razem z nieaktywnymi
systemctl list-timers --all

# Logi z backup.service (ostatnie uruchomienia)
journalctl -u backup.service --since today

# Logi z ostatniej godziny
journalctl -u backup.service --since "1 hour ago"

# Follow logow (tail -f)
journalctl -u backup.service -f

# Reczny start service (test bez czekania na timer)
sudo systemctl start backup.service

Porównanie: cron vs systemd timer

Cecha cron systemd timer
Prostota składni Bardzo prosta Złożona (2 pliki)
Logowanie Ręczne (redirect) journalctl (automatyczne)
Catchup (Persistent) Brak (anacron osobno) Wbudowane (Persistent=true)
Randomized delay Brak RandomizedDelaySec
Zależności Brak After, Requires, Wants
Monitoring stanu Brak systemctl status
Resource limits Brak Nice, IOClass, MemoryMax
OnBootSec (po starcie) @reboot (prymitywne) OnBootSec (dokładne)

Zaawansowane wzorce OnCalendar i OnBootSec

Timer ma dwa niezależne typy wyzwalaczy: calendar-based (OnCalendar) i monotonic (OnBootSec, OnStartupSec, OnUnitActiveSec, OnUnitInactiveSec). Calendar jest czasem zegarowym (np. codziennie o 3:00), monotonic jest liczony od konkretnego zdarzenia (np. 5 minut po starcie systemu).

[Timer]
# Codziennie o polnocy
OnCalendar=daily

# Pierwszy dzien miesiaca
OnCalendar=monthly

# Pon-Pt o 9:00
OnCalendar=Mon..Fri 09:00

# Co 15 minut
OnCalendar=*:0/15

# 15 minut po starcie systemu
OnBootSec=15min

# 5 minut po starcie + co 30 minut pozniej
OnBootSec=5min
OnUnitActiveSec=30min

# Kilka roznych czasow dziennie
OnCalendar=*-*-* 06,12,18,22:00:00

# Test wyrazenia OnCalendar
# systemd-analyze calendar "Mon..Fri 09:00"
# -> Next elapse: Mon 2026-04-13 09:00:00 UTC

Komenda systemd-analyze calendar "wyrażenie" to nieoceniony helper — pozwala sprawdzić, czy twoje wyrażenie OnCalendar jest poprawne i kiedy dokładnie zostanie uruchomione następnym razem. Używaj jej zanim zapiszesz plik timer — oszczędzi wiele nerwów.

Najczęstsze pytania

Czy systemd timer zastąpi crona w każdym przypadku? +
Tak, dla większości zadań systemd timer ma więcej możliwości niż cron: dokładniejszy harmonogram (OnCalendar), integracja z loggiem (journalctl), zależności między jednostkami, Persistent=true (catchup po downtime). Cron dalej jest prostszy dla jednorazowych, prostych zadań.
Co to jest Persistent=true w systemd timer? +
Persistent=true zapisuje na dysku ostatni czas uruchomienia jednostki. Jeśli serwer był offline i przeoczył zaplanowany czas, timer uruchomi zadanie od razu po boot (catchup). Cron nie ma tej funkcji — przeoczone zadania są stracone.
Jak sprawdzić status wszystkich timerów systemd? +
systemctl list-timers pokazuje wszystkie aktywne timery z następnym czasem uruchomienia, ostatnim uruchomieniem i powiązaną jednostką service. Dodaj --all żeby zobaczyć też nieaktywne, lub systemctl status nazwa.timer dla szczegółów.
Co robi RandomizedDelaySec? +
RandomizedDelaySec dodaje losowe opóźnienie (0 do X sekund) do zaplanowanego czasu uruchomienia. Przydatne, gdy masz wiele serwerów z tym samym cronem — zamiast wszystkich uderzać w bazę jednocześnie, rozkłada się ruch w czasie. Np. RandomizedDelaySec=300 dodaje 0-5 minut delay.

Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.