- Timer systemd adalah pengganti praktis untuk
cron, yang menjalankan unit seperti .service sesuai jadwal serta membuat pengelolaan riwayat, output, dan lingkungan lebih jelas
cron tradisional punya beberapa kelemahan praktis: $PATH yang ambigu, stdout/stderr yang mudah hilang, riwayat eksekusi yang sulit dilacak, dan sintaks jadwal yang sulit dibaca
- Timer menghubungkan
.timer dan .service dengan stem yang sama, dan mengekspresikan eksekusi berbasis waktu maupun event melalui OnCalendar, OnBootSec, dan OnUnitActiveSec
- Dengan
systemd-analyze calendar dan systemctl list-timers, Anda bisa memeriksa ekspresi waktu dan waktu eksekusi berikutnya, sementara WakeSystem= dapat membangunkan sistem untuk menjalankan tugas bahkan saat dalam mode suspend
RandomizedOffsetSec dan FixedRandomDelay= membantu mengurangi lonjakan eksekusi serentak, dan Persistent= menebus eksekusi yang terlewat saat offline segera setelah sistem kembali online
Alasan memakai timer systemd sebagai pengganti cron
- Istilah
cron job digunakan luas untuk menyebut elemen dasar komputasi yang menjalankan tugas berdasarkan jadwal seperti “jalankan ini setiap hari” atau “jalankan itu setiap bulan”, bahkan bila daemon cron yang sebenarnya tidak dipakai
- Timer systemd adalah unit systemd yang menjalankan unit lain, biasanya
.service, sesuai jadwal tertentu, dan dapat menjadi pengganti fungsional untuk daemon cron tradisional
cron tradisional memiliki beberapa kelemahan praktis
- Konfigurasi
$PATH yang ambigu membuat hasil eksekusi skrip sulit diprediksi
- Output
stdout dan stderr sering masuk ke lubang hitam atau dikirim ke sistem mail host
- Riwayat eksekusi sulit dilacak dan di-query
- Sintaks jadwal seperti
01,31 04,05 1-15 1,6 * tidak mudah dibaca atau intuitif bagi manusia
- Timer systemd mengurangi masalah tersebut sambil tetap menyediakan pengaturan kalender yang mirip dengan gaya ekspresi
cron
Struktur dasar: service dan timer
- Timer systemd memerlukan target eksekusi, dan unit
.service secara logis bisa dipandang seperti skrip
- Sebagai contoh, jika Anda menaruh unit berikut di
/etc/systemd/system/roulette.service, Anda akan memasang layanan yang mematikan komputer dengan peluang 1 banding 10
[Unit]
Description=1 in 10 chance to break your chains
[Service]
ExecStart=/usr/bin/env bash -c '[[ $(($RANDOM % 10)) == 0 ]] && systemctl poweroff || echo LIVE ANOTHER DAY'
ExecCondition= adalah cara yang lebih terintegrasi untuk mengekspresikan eksekusi bersyarat sebagai opsi layanan systemd, dan menampilkan “apakah ini harus terus dijalankan?” dengan lebih jelas di level unit
[Unit]
Description=1 in 10 chance to break your chains
[Service]
ExecCondition=/run/current-system/sw/bin/bash -c '[[ $(($RANDOM % 10)) == 0 ]]'
ExecStart=/run/current-system/sw/bin/systemctl poweroff
- Jika kondisi tidak terpenuhi, jurnal akan mencatat pesan yang lebih jelas
May 05 11:05:32 diesel systemd[3117]: Condition check resulted in 1 in 10 chance to break your chains being skipped.
- Secara umum, memanfaatkan opsi yang disediakan systemd memberi pengalaman yang lebih baik daripada menulis skrip sendiri
OnFailure= dapat dipakai saat ingin merespons kegagalan skrip layanan
Restart= dapat dipakai saat ingin mencoba pulih dari kegagalan sementara
Menghubungkan dan menjalankan unit timer
- Jika Anda menaruh
/etc/systemd/system/roulette.timer dengan stem file yang sama, Anda bisa menghubungkan timer ke roulette.service
[Unit]
Description=impending destruction
[Timer]
OnCalendar=10:00
[Install]
WantedBy=timers.target
- Secara default, pengaturan
Unit= pada timer akan memilih unit layanan dengan .service yang ditambahkan ke stem yang sama
- Dalam contoh ini, yang dipilih adalah
roulette.service
- Jika ingin menjalankan unit layanan dengan nama lain, Anda bisa mengubah
Unit=
- Target
ExecStart= secara default tidak dijalankan sebagai perintah shell
- Target dengan path absolut harus diperlakukan sebagai skrip, atau sebagai interpreter yang mengharapkan skrip dalam argumen string
ExecStart=/usr/bin/echo Hello | /usr/bin/awk tidak akan bekerja di konteks ini karena pipe tidak bermakna
- Argumen
ExecStart= secara default tidak mewarisi variabel lingkungan selain beberapa default dari system manager
$PATH default nyaris kosong
- Menjalankan
/usr/bin/env menjadi perlindungan sederhana agar item seperti systemctl dapat digunakan
- Jika hanya menulis
ExecStart=/usr/bin/bash, $PATH akan berisi item default, tetapi memakai env adalah pengaman tambahan
- Layanan bisa dijalankan langsung tanpa timer
systemctl start roulette
- Layanan tanpa bagian
[Install] tidak bisa di-enable, dan dalam struktur ini timer adalah cara standar untuk menjalankan layanan secara konsisten
systemctl secara default bekerja pada roulette.service meski akhiran tidak ditulis eksplisit
- Menerapkan
systemctl start pada unit .timer membuat timer menjadi aktif, tetapi tidak langsung menjalankan layanan target Unit=
systemctl start roulette.timer
status akan menunjukkan kapan timer akan dijalankan berikutnya
systemctl status roulette.timer
Trigger: Sat 2026-04-18 10:00:00 MDT; 35min left
- Alur paling sederhana adalah membuat layanan target eksekusi, menaruh timer dengan jadwal di lokasi yang sama, lalu memulai timer, bukan targetnya
- Jika
[Install] pada unit timer memiliki WantedBy=, timer juga bisa dijalankan saat boot
systemctl enable roulette.timer
Ekspresi waktu: event kalender dan durasi
- Dalam timer, cara mengekspresikan jadwal itu penting, dan perlu dibedakan antara rentang waktu berulang dengan event kalender atau stempel waktu
- Manual
systemd.time(7) punya cukup banyak contoh dan layak jadi referensi pertama saat menulis timer
systemd-analyze dapat memvalidasi dan menjelaskan ekspresi waktu
systemd-analyze calendar '*-*-* *:*:*'
Normalized form: *-*-* *:*:*
Next elapse: Sat 2026-04-18 16:44:26 MDT
(in UTC): Sat 2026-04-18 22:44:26 UTC
From now: 431ms left
- Timer systemd tidak hanya bisa mendefinisikan waktu berulang berbasis jam dinding, tetapi juga, tidak seperti
cron tradisional, durasi berulang yang dihitung dari event sebelumnya
- Bentuk lengkap
daily berarti dijalankan setiap tahun, setiap bulan, setiap hari pada pukul 00:00:00
*-*-* 00:00:00
│ │ │ │ │ ╰── at second 00
│ │ │ │ ╰───── at minute 00
│ │ │ ╰──────── at hour 00
│ │ ╰────────── every day
│ ╰──────────── every month
╰────────────── every year
- Anda bisa memakai singkatan seperti
daily, bentuk lengkap, atau nilai lain yang didukung systemd.time(7), lalu memverifikasi asumsi dengan systemd-analyze
Saat eksekusi berbasis event lebih cocok
- Dalam pekerjaan nyata, sering kali “jalankan setelah event lain” lebih cocok daripada “jalankan pada jam yang sama setiap hari”
- Pekerjaan membersihkan direktori sementara mungkin hampir tidak punya apa pun untuk dibersihkan di
/tmp jika ekspresi cron untuk sesaat setelah boot sudah terlewat
- Mengekspresikannya sebagai “jalankan satu jam setelah komputer mulai, lalu setiap satu jam setelah itu” lebih sesuai dengan perilaku layanan yang sebenarnya dan logika penjadwalannya
[Timer]
OnBootSec=1h
OnUnitActiveSec=1h
OnBootSec=1h berarti dijalankan sekali satu jam setelah mesin menyala
OnUnitActiveSec=1h berarti dijalankan lagi satu jam setelah Unit= dieksekusi, sehingga timer secara implisit terus berulang
- Ekspresi durasi periodik seperti ini lebih sering cocok untuk penggunaan “jalankan sesekali” daripada ekspresi seperti “jalankan pada menit ini setiap jam”
- Dalam contoh bot Slack yang melakukan polling API Advent of Code, ekspresi cron
*/15 memang mematuhi kebijakan API “setiap 15 menit”, tetapi jika semua orang melakukan polling dengan cara yang sama, lalu lintas bisa menumpuk
- Jika timer dimulai setelah perubahan kode lalu dijalankan setiap 15 menit sesudahnya, perilaku yang dibutuhkan tetap terpenuhi sambil berpotensi mengurangi masalah thundering herd
Melihat status timer secara sekilas
systemctl list-timers adalah perintah tingkat tinggi yang merangkum kondisi timer pada sebuah mesin
systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon 2026-04-20 15:15:00 MDT 1min 40s Mon 2026-04-20 15:00:05 MDT 13min ago zfs-snapshot-frequent.timer zfs-snapshot-frequent.service
Mon 2026-04-20 15:32:16 MDT 18min Mon 2026-04-20 14:22:15 MDT 51min ago fwupd-refresh.timer fwupd-refresh.service
Mon 2026-04-20 16:00:00 MDT 46min Mon 2026-04-20 15:00:05 MDT 13min ago logrotate.timer logrotate.service
Mon 2026-04-20 16:00:00 MDT 46min Mon 2026-04-20 15:00:05 MDT 13min ago zfs-snapshot-hourly.timer zfs-snapshot-hourly.service
Tue 2026-04-21 00:00:00 MDT 8h Mon 2026-04-20 09:43:22 MDT 5h 29min ago zfs-snapshot-daily.timer zfs-snapshot-daily.service
Tue 2026-04-21 07:31:28 MDT 16h Sun 2026-04-19 20:15:47 MDT 7h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Mon 2026-04-27 00:00:00 MDT 6 days Mon 2026-04-20 09:43:22 MDT 5h 29min ago zfs-snapshot-weekly.timer zfs-snapshot-weekly.service
Mon 2026-04-27 01:09:27 MDT 6 days Mon 2026-04-20 09:43:22 MDT 5h 29min ago fstrim.timer fstrim.service
Mon 2026-04-27 04:28:38 MDT 6 days Mon 2026-04-20 09:43:22 MDT 5h 29min ago zpool-trim.timer zpool-trim.service
Fri 2026-05-01 00:00:00 MDT 1 week 3 days Wed 2026-04-01 10:07:51 MDT 1 week 1 day ago zfs-snapshot-monthly.timer zfs-snapshot-monthly.service
Fri 2026-05-01 03:17:17 MDT 1 week 3 days Wed 2026-04-01 10:07:51 MDT 1 week 1 day ago zfs-scrub.timer zfs-scrub.service
11 timers listed.
Pass --all to see loaded but inactive timers, too.
- Dengan satu perintah, Anda bisa mendapatkan gambaran menyeluruh tentang item-item yang dijalankan menurut jadwal timer
list-timers adalah bagian dari keluarga subperintah systemd yang sering dipakai
list-units juga berguna
list-paths adalah subperintah yang lebih baru ditambahkan ke systemctl
Bangunkan sistem dari mode suspend untuk menjalankan tugas
WakeSystem= dapat membuat timer yang waktunya tiba membangunkan sistem dari mode suspend
WakeSystem=
Takes a boolean argument. If true, an elapsing timer will
cause the system to resume from suspend, should it be
suspended and if the system supports this.
...
- Fitur ini berguna saat skrip penting perlu dijalankan tanpa harus menunggu tindakan fisik seseorang membuka tutup laptop
- Pada distribusi seperti Arch atau NixOS yang mendukung pengunduhan pembaruan paket sebelum dipakai, Anda bisa mengambil paket pembaruan larut malam dan melakukan pembaruan saat pagi hari sudah berada di depan keyboard
- Manual menyebutkan bahwa jika ingin kembali masuk mode suspend setelah
.service selesai, Anda harus menangani suspend ulang itu secara manual
Menyebarkan waktu eksekusi dan meredam thundering herd
- Masalah thundering herd adalah masalah sistem yang terjadi saat banyak proses bangun pada saat yang sama
- Jika semua sistem Debian di seluruh dunia di-hardcode untuk menjalankan
apt update pada 00:00:00, tengah malam akan menjadi puncak trafik yang buruk bagi semua orang
FixedRandomDelay= dan RandomizedOffsetSec= membantu menyebarkan waktu eksekusi
FixedRandomDelay=
Takes a boolean argument. When enabled, the randomized delay
specified by RandomizedDelaySec= is chosen deterministically,
and remains stable between all firings of the same timer,
even if the manager is restarted. ...
RandomizedOffsetSec=
Offsets the timer by a stable, randomly-selected, and evenly
distributed amount of time between 0 and the specified time
value. ...
- Pengaturan seperti ini bisa dipakai pada sistem nyata yang memeriksa pembaruan perangkat lunak
- Menyebarkan eksekusi secara merata membantu mengurangi masalah thundering herd, membuat perilaku lebih konsisten, dan membantu menghindari gangguan seperti restart daemon yang sedang mengoordinasikan layanan terdistribusi
- Opsi timing secara umum sangat bisa dikonfigurasi dan memberi kontrol yang rinci
Segera menebus eksekusi yang terlewat
Persistent= sangat cocok terutama untuk skrip terjadwal yang tidak boleh terlewat hanya karena laptop sedang suspend, tetapi juga tidak sampai memerlukan WakeSystem=
Persistent=
Takes a boolean argument. If true, the time when the service
unit was last triggered is stored on disk. When the timer is
activated, the service unit is triggered immediately if it
would have been triggered at least once during the time when
the timer was inactive. ...
- Jika sistem yang menjadwalkan check-in manajemen konfigurasi mengalami downtime, cukup menaruh
Persistent= pada .timer dapat membuatnya kembali menuju keadaan yang benar segera setelah online
- Tanpa
Persistent=, Anda mungkin harus menunggu sampai waktu eksekusi normal timer berikutnya, dan itu bisa memakan waktu lama
- Pekerjaan lain yang juga tidak boleh menunggu saat aktivasi terlewat terdeteksi antara lain pembaruan sistem dan pemeriksaan batch job
Hal yang perlu diperhatikan saat menulis timer
- Timer dalam konteks user manager yang dikelola dengan
systemctl --user juga valid, tetapi perhatikan target yang dipakai di [Install]
- Bergantung pada distribusinya, target yang tepat untuk timer pengguna bisa jadi
default.target
- Seperti pada
cron, catatan umum bahwa jam sistem harus akurat tetap berlaku
- Pengguna systemd dapat memeriksa status sinkronisasi dengan
timedatectl timesync-status
- Banyak editor sudah mendukung format file unit systemd secara bawaan, yang membantu saat file unit mulai membesar
- Di Emacs, Anda bisa memakai paket emacs systemd
1 komentar
Opini Lobste.rs
systemd memang tidak sempurna, tetapi terasa banyak keputusan desainnya didasarkan pada pelajaran yang didapat dari cara-cara lama yang lebih tradisional
Baru-baru ini saya mendengarkan lagi episode CRE tahun 2015 di mana Lennart Poettering menjelaskan latar belakangnya, dan itu masih layak direkomendasikan sampai sekarang
Saya termasuk pihak yang benar-benar tidak suka systemd, tetapi systemd.timers menurut saya adalah salah satu konsep yang “lumayan lebih baik” dalam produk ini
Karena itu, agak mengejutkan melihat penulis membelanya dengan cara yang terkesan meremehkan orang-orang yang punya keluhan yang masuk akal
Meski begitu, saya suka memakainya bersama perintah
at. Untuk perintah yang dijalankan sekali pada waktu tertentu, pakaiat, selain itu pakai timer systemd dan unit file sederhanaPeningkatan yang paling ingin saya lihat adalah kemampuan mengetahui pengguna mana yang sedang menjalankan timer. Saya memang salah satu dari sedikit orang yang masih mengelola shellbox pada 2026, tetapi akan berguna jika saya bisa tahu pengguna mana yang membuat timer yang mengakses disk setiap detik
Setahu saya, dengan
loginctl enable-linger, itu bisa berjalan bahkan tanpa sesi pengguna yang aktif. Tentu saja ada kasus penggunaan yang mungkin tidak cukup ditangani dengan itu, dan saya tidak tahu situasi spesifiknyaAkan lebih baik kalau systemd timer punya hambatan awal yang lebih rendah, terutama di sisi pengelolaan pengguna
Kalau melihat jumlah konfigurasi yang dibutuhkan, sangat sulit mengalahkan
crontab -eSaya sudah lama memikirkan cara mengumpulkan log skrip cron secara terstruktur, lalu sadar bahwa saya bisa langsung memakai systemd timer
Masalah logging pun selesai. Sekarang tidak ada alasan untuk kembali memakai cron, dan saya berharap tahu ini lebih cepat
logger, atau ditambahkan ke file log dengan>>, atau dibiarkan default lalu menerima email?Silakan bilang ini kuno, tapi saya masih menyiapkan email dari server untuk sampai ke saya
Kalau diotomatisasi, itu ikut tersedia gratis di setiap host baru, dan dalam penggunaan sehari-hari juga cukup nyaman
Misalnya, saya cukup membuka satu multiplexer lalu menjalankan
long_running_process | mail root@localhost -s "done $?"dan melupakannyaTulisan yang bagus, dan saya juga punya draf tulisan serupa yang belakangan harus saya rujuk lagi
Jika Anda seperti saya dan masuk ke lubang kelinci systemd, saya sarankan membuat tautan simbolis untuk unit file dan timer di folder proyek terkait ke
/etc/systemd/system/Salah satu keluhan saya terhadap systemd adalah distribusi tidak membedakan unit yang dipasang distro dengan unit yang saya tulis sendiri, dan dengan tautan simbolis saya bisa menjaga pemisahan itu sendiri
Unit sistem/paket/distribusi masuk ke
/usr/lib/systemd/system, sedangkan override lokal atau unit lokal masuk ke/etc/systemd/system