Bumalik sa blog

Cron vs systemd timers: alin ang gagamitin mo?

Setyembre 11, 2026

Sa modernong distro, systemd timer ang gamitin sa kahit anong job na pag-aari mo, at panatilihin ang cron para sa one-line na user jobs at sa mga server na hindi mo in-setup. Naka-log ang bawat run ng timer sa journal, kayang habulin ang mga schedule na na-miss habang patay ang makina, at nakadepende ito sa parehong unit files na ginagamit ng lahat ng iba sa system. Panalo ang cron sa ikli — isang crontab -e linya laban sa dalawang unit files — at ito pa rin ang tanging scheduler na siguradong nandoon sa minimal containers at exotic na Unix boxes. Ang huli: tahimik na nag-fa-fail ang cron. Kung mag-error ang job mo ng 3 a.m., nagmemail ang cron sa local mailbox na walang nagbabasa, samantalang bibigyan ka ng timer ng journalctl -u mytimer.service na may buong output. Sa ibaba: ang totoong mga pagkakaiba, kung paano i-test ang bawat isa, kung bakit hindi nagti-trigger ang timer, at isang decision table.

Ano ang pagkakaiba ng cron at systemd timer?

Ang cron ay isang daemon na nagbabasa ng table ng mga linya — limang time field at isang command — at nagpapatakbo ng bawat command kapag tumugma ang wall clock. Iyon ang buong model nito. Walang konsepto ng job bilang object: walang unit, walang status, walang dependencies, walang sariling log entry.

Ang systemd timer ay isang unit file (foo.timer) na nag-fi-fire ng isa pang unit file (foo.service) kapag tumugma ang schedule nito. First-class object ang job — may start, status, logs, at failure tracking na katulad ng ibang service. Ang scheduling ay calendar-based (parang cron) o monotonic (OnBootSec=15min, na hindi maguluhan ng mga pagbabago sa wall clock).

Ang mga praktikal na epekto:

  • Logging: naka-log sa journal ng timers ang stdout/stderr per unit; sa pinakamaganda, nagmemail ang cron sa local user.
  • Mga missed run: isang beses tumatakbo sa boot ang timer na may Persistent=true kapag na-miss ang schedule nito; nilalaktawan lang ito ng cron.
  • Mga dependency: pwedeng maghintay ang timers sa network-online.target o mga mount point; kailangan mong de kamay na magsulat ng retry logic sa script para sa cron.
  • Syntax: isang linya ang cron; dalawang files ang timer. Iyan ang kabuuang halaga ng paglipat.

Alin ang mas madaling schedule syntax — crontab o OnCalendar?

Ang limang field ng cron ang compact na kasalukuyang nakaluklok: */15 * * * * ay kada 15 minuto, at kabisado ng karamihan sa mga admin ang mga ito. Mas mabigat basahin ang OnCalendar= ng systemd pero mas malawak talaga ang kayang i-express, at sasabihin ng systemd-analyze calendar ang mga susunod na run bago ka pa mag-commit — walang katumbas na dry-run ang cron.

# Cron: every day at 03:30
30 3 * * * /usr/local/bin/backup.sh

# systemd: the same schedule, verifiable before you save it
systemd-analyze calendar "*-*-* 03:30:00"
# -> Next elapse: Fri 2026-09-11 03:30:00 ...

Kinakaya ng OnCalendar ang mga bagay na hindi talagang malinis na ma-express ng cron: Mon..Fri *-*-* 09..17:00:00 (weekdays, business hours), o *:0/15 na may RandomizedDelaySec=10m para hindi sabay-sabay na saksakin ng isang libong makina ang isang server sa iisang sandali.

Paano ko i-test ang systemd timer nang hindi naghihintay?

Tatlong command ang sagot sa lahat. Ilista ang naka-iskedyul at kailan ang susunod na fire, i-run nang mano-mano ang job eksakto kung paano ito gagawin ng timer, tapos basahin ang logs nito:

systemctl list-timers --all                 # every timer, next + last run
sudo systemctl start backup.service         # fire the job now, same unit as the timer
journalctl -u backup.service -f             # watch its output live

Tandaan ang paghahati: ina-arm ng systemctl start backup.timer ang schedule; ang service ang job. Kapag ipinapakita ng list-timers ang timer mo, berde ang systemctl status backup.service, at ipinapakita ng journal ang output mo, gumagana ang buong chain.

Paano ko i-run nang mano-mano ang cron job?

Tumatakbo ang mga cron job na may stripped na environment — kaya isang genre na ng bug ang “works in my shell, fails in cron”. Para maging tapat ang pag-reproduce sa cron, i-run ang command sa sh na may parehong environment na gagamitin ng cron:

crontab -l                                  # confirm the exact line
env -i SHELL=/bin/sh PATH=/usr/bin:/bin sh -c '/usr/local/bin/backup.sh'
grep CRON /var/log/syslog | tail            # did cron even fire it? (Debian/Ubuntu)
journalctl -u cron -n 20                    # same, on systemd distros

Ang env -i linyang iyan ang tapat na manual test: bare na environment na may default na PATH ng cron. Karamihan sa tahimik na pagkabigo ng cron ay bare na PATH o hindi naka-quote na % sa command (itinuturing ng cron na newline ang %), at parehong lumilitaw agad sa paraang ito.

Bakit hindi nagti-trigger ang systemd timer ko?

Apat na sanhi ang sumasaklaw sa halos lahat ng kaso, sa ayos ng pag-check:

  1. Hindi tugma ang pangalan ng service at ng timer. Nag-fi-fire ang foo.timer ng foo.service — isang napagkamalang OnFailure o pinalitan ng pangalan na unit ay nangangahulugang walang tinatamaan ang “run” ng timer. Ipinapakita ng systemctl cat foo.timer kung ano eksakto ang target nito.
  2. Nina-edit ang timer pero hindi na-reload. Pagkatapos magbago ang isang unit file: sudo systemctl daemon-reload && sudo systemctl restart foo.timer. Kapag wala ito, hindi live ang bagong schedule mo.
  3. Persistent=true nang walang OnCalendar semantics na inaasahan mo — o tinitingnan mo ang systemctl status foo.timer (laging active kahit idle) sa halip na list-timers.
  4. Ang service na ini-fire nito ay biglaang bumibigo, kaya mukhang patay ang timer. Ipinapakita ng journalctl -u foo.service --since -1h ang crash na itinatago ng list-timers.

At kapag tinitingnan mo na ang mga log, sakop ng journalctl cheat sheet ang mga filter (-u, --since, -f) na nagpapabilis nito.

Cron vs systemd timers: ang decision table

cronsystemd timer
Setupisang crontab linyadalawang unit files
Logginglocal mail, hindi genap nababasajournal, per unit
Missed run (patay ang makina)nilalaktawanisang beses tumatakbo kapag may Persistent=true
Mga dependency / orderingwala — DIY sa scriptkumpletong unit dependencies
Random na delayDIY gamit ang $RANDOMRandomizedDelaySec=
Test/dry-run ng schedulewalasystemd-analyze calendar
Nasa lahat ng dakooo — containers, BSD, embeddedkailangan ng systemd (PID 1)
User jobs nang walang rootcrontab -esystemd --user units

Mga rule of thumb: magpapadala ka ng job sa sarili mong systemd machine → timer. Mabilisang personal na paalala o box na hindi mo binuo → cron. Kahit anong may dependencies, retries, o pangangailangang malaman kung tumakbo nga → timer, lagi. Karaniwang pattern ay isang timer na nagpapatakbo ng maintenance job — sabihin na nating nightly na rsync backup — kung saan ginagarantiya ng Persistent=true na mangyayari ang backup kahit natutulog ang makina sa naka-iskedyul na minuto, na hindi talagang kayang i-offer ng cron.

FAQ

Deprecated na ba ang cron jobs sa Linux?

Hindi — okay lang ang cron para sa simpleng time trigger. Panalo ang timers kapag kailangan mo ng catch-up sa mga missed run, dependencies, o logs sa journal.

Ano ang kayang gawin ng systemd timer na hindi kaya ng cron?

Muling pinapatakbo ng persistent timer ang mga missed job pagkatapos ng downtime; tahimik na nilalaktawan ito ng cron. Kayang mag-chain ng dependencies ang timer at pwedeng i-randomize ang start window.

Paano ko i-debug ang timer na hindi tumakbo?

Ipinapakita ng systemctl list-timers --all ang huling at susunod na run; ang journalctl -u sa timer at sa service unit nito ang nagpapakita kung bakit ito nag-fire o nag-fail.

— mrsaynothing

— mrsaynothing

Mga field note sa AI, Linux at self-hosting.

Pag-usapan ang post na ito sa dev.to dev.to ↗

Ang susunod na how-to sa email

Isang email kada post. Ayusin, tuloy sa susunod.

self-hosted · walang third parties · one-click unsubscribe

ano ito?

llama.cpp vs Ollama: Alin ang I-run Mo sa 2026?

Nag-e-enjoy ka ba sa mga sulat na ito? Ito ang tinatayo ko para sa trabaho. i-hire ako