Penjadwalan mengubah DAG dari kode yang dijalankan secara manual menjadi pipeline yang berjalan sendiri mengikuti waktu tertentu. Topik ini membahas parameter schedule beserta preset dan string cron, penerjemahan jadwal menjadi timetable, serta dua nilai yang menyertai setiap dag run, yaitu logical date dan data interval. Perilaku catchup yang menentukan apakah run untuk pemicuan yang terlewat tetap dibuat juga diuraikan, sehingga pemicuan DAG berikutnya dapat diprediksi dengan pasti.
Preset jadwal dan string cron#
Nilai parameter schedule pada decorator @dag menentukan kapan scheduler membuat dag run secara otomatis. Parameter ini menerima preset seperti @daily, string cron, atau None. Nilai None menonaktifkan penjadwalan sepenuhnya, sehingga DAG hanya dapat dipicu secara manual atau dari program lain.
Preset menyingkat ekspresi cron, yaitu notasi lima kolom untuk jadwal berulang yang paling sering digunakan. String cron memberi kendali penuh atas kelima kolom tersebut, yaitu menit, jam, hari dalam sebulan, bulan, dan hari dalam seminggu. Tabel berikut membandingkan preset bawaan dengan string cron yang setara.
| Preset | String cron setara | Arti |
|---|---|---|
@hourly | 0 * * * * | Setiap awal jam |
@daily | 0 0 * * * | Setiap tengah malam |
@weekly | 0 0 * * 0 | Setiap hari Minggu tengah malam |
@monthly | 0 0 1 * * | Setiap tanggal 1 tengah malam |
@yearly | 0 0 1 1 * | Setiap 1 Januari tengah malam |
Berdasarkan urutan kolom tersebut, string "0 9 * * *" berarti setiap hari pukul 09:00. Tanda bintang menyatakan setiap nilai pada kolomnya. Jadwal dievaluasi terhadap zona waktu DAG, yang secara bawaan adalah UTC dan dapat diganti melalui konfigurasi default_timezone. Nilai schedule disimpan apa adanya, sehingga string yang ditulis dapat ditanyakan kembali dari objek DAG melalui atribut schedule, dan pemeriksaan itu dipraktikkan pada bagian berikutnya.
Timetable bawaan dan logical date#
String dan preset jadwal tidak langsung digunakan oleh scheduler, melainkan diterjemahkan menjadi objek timetable, yakni komponen yang memutuskan kapan sebuah dag run dibuat. Airflow 3 menggunakan CronTriggerTimetable untuk string cron, yaitu timetable yang memicu run pada setiap waktu yang cocok dengan ekspresi cron-nya. Setiap run yang dihasilkan membawa logical date, yaitu tanggal yang mengidentifikasi run tersebut pada kalender jadwal.
Berkas dag_laporan.py berikut membangun DAG laporan dengan dua task berurutan. Parameter schedule diisi string cron "0 9 * * *".
from airflow.providers.standard.operators.bash import BashOperator
from airflow.sdk import dag
@dag(
dag_id="dag_laporan",
schedule="0 9 * * *",
description="Laporan harian yang berjalan setiap pukul 09:00.",
)
def dag_laporan():
kumpul = BashOperator(task_id="kumpul_data", bash_command="echo 'Kumpul data'")
susun = BashOperator(task_id="susun_laporan", bash_command="echo 'Susun laporan'")
kumpul >> susun
dag_laporan()Struktur jadwalnya dapat diperiksa dari objek DAG yang sudah dimuat. Atribut schedule mengembalikan string yang ditulis, sedangkan objek timetable menunjukkan hasil penerjemahannya.
# arahkan metadata Airflow ke folder kerja sementara
export AIRFLOW_HOME=/tmp/ra-penjadwalan
# muat DAG lalu baca identitas, jadwal, dan timetable-nya
python3 -c "import dag_laporan; d = dag_laporan.dag_laporan(); print(d.dag_id); print(d.schedule); print(repr(d.timetable))"dag_laporan
0 9 * * *
CronTriggerTimetable(expression='0 9 * * *', timezone=Timezone('UTC'), interval=datetime.timedelta(0), run_immediately=False)Keluaran memuat tiga baris yang saling melengkapi. Dua baris pertama menegaskan bahwa atribut schedule menyimpan string cron persis seperti yang ditulis. Baris ketiga menunjukkan bahwa scheduler bekerja dengan CronTriggerTimetable yang menggunakan zona waktu UTC, dan bagian interval=datetime.timedelta(0) menyatakan lebar data interval bawaan bernilai nol. Data interval itu sendiri diuraikan pada bagian berikutnya. Dengan lebar nol, logical date sebuah run sama dengan waktu pemicuannya, sehingga run yang dipicu pukul 09:00 pada tanggal 2026-11-04 membawa logical date 2026-11-04 09:00:00.
Data interval dan pola klasik#
Setiap dag run bekerja atas sebuah data interval, yaitu rentang waktu berbentuk [mulai, selesai) yang menyatakan periode data yang diproses. Notasi [mulai, selesai) berarti batas mulai termasuk di dalam rentang, sedangkan batas selesai tidak termasuk, sehingga dua interval berturut-turut tidak saling tumpang tindih. Airflow juga menyediakan CronDataIntervalTimetable, pola data interval klasik yang menjadi bawaan Airflow 2.x, dan pola inilah yang mengisi rentang tersebut secara penuh.
Pada pola klasik tersebut, batas selesai interval bertepatan dengan waktu pemicuan run, sedangkan logical date berpindah menjadi batas mulainya. Sebuah run cron "0 9 * * *" yang dipicu pada pagi 2026-11-04 dengan pola ini memproses data interval [2026-11-03 09:00, 2026-11-04 09:00). Run tersebut membawa logical date 2026-11-03 09:00:00, sehingga hari yang diproses adalah hari sebelumnya. Perhitungan yang sama pada jadwal @daily memberikan run yang dipicu tepat pada 2026-11-04 00:00 untuk interval [2026-11-03 00:00, 2026-11-04 00:00).
Batas-batas interval itu mudah dihitung ulang dengan pendulum, library tanggal dan waktu yang juga digunakan di dalam Airflow. Skrip berikut menghitung interval untuk run @daily pola klasik yang dipicu tepat tengah malam 2026-11-04.
import pendulum
# run @daily pola klasik yang dipicu tepat tengah malam 2026-11-04
pemicu = pendulum.datetime(2026, 11, 4, tz="UTC")
# interval berakhir pada waktu pemicuan dan berjarak satu hari
mulai = pemicu.subtract(days=1)
print(f"Pemicuan : {pemicu.to_datetime_string()}")
print(f"Logical date : {mulai.to_datetime_string()}")
print(f"Data interval: [{mulai.to_datetime_string()}, {pemicu.to_datetime_string()})")Pemicuan : 2026-11-04 00:00:00
Logical date : 2026-11-03 00:00:00
Data interval: [2026-11-03 00:00:00, 2026-11-04 00:00:00)Keluaran menegaskan dua hal sekaligus. Interval run yang dipicu pada 2026-11-04 memang mencakup hari sebelumnya, sehingga task di dalamnya membaca data bertanggal 2026-11-03. Logical date yang dimiliki run justru merupakan tanggal data tersebut, bukan tanggal task benar-benar berjalan, dan perbedaan inilah sumber kebingungan yang paling sering muncul saat membaca riwayat run pada UI.
Catchup#
Catchup adalah perilaku scheduler yang membuat dag run untuk pemicuan yang terlewat, misalnya karena DAG baru diterapkan atau pernah nonaktif. Apabila catchup aktif, scheduler membuat run untuk setiap pemicuan yang terlewat sejak start_date DAG, yaitu batas awal kapan DAG dianggap berlaku. Apabila catchup tidak aktif, run pertama hanya dibuat untuk pemicuan berikutnya, sedangkan interval yang terlewat dibiarkan kosong hingga diisi secara manual.
Airflow 3 menonaktifkan catchup secara bawaan. Catchup tidak lagi menjadi argumen DAG seperti pada Airflow 2.x, yang bawaannya True. Pada Airflow 3, perilaku ini dikendalikan oleh konfigurasi catchup_by_default pada kelompok scheduler. Nilai bawaan tersebut dapat dibaca langsung dari perintah konfigurasi Airflow.
# baca nilai bawaan catchup_by_default pada kelompok scheduler
airflow config get-value scheduler catchup_by_defaultFalseNilai False berarti DAG terjadwal yang baru diterapkan tidak langsung dibuatkan run untuk masa lalu, dan run pertamanya menunggu pemicuan berikutnya. Perbedaan perilaku ini perlu diperhatikan ketika memindahkan DAG dari Airflow 2.x, karena DAG yang dulu otomatis membuat run untuk riwayat kini berhenti pada pemicuan terdekat. Interval yang terlewat tetap dapat diisi kemudian melalui backfill, yaitu menjalankan run untuk interval tertentu secara manual.
Ringkasan#
- Parameter
schedulemenerima preset, string cron, atauNone, dan Airflow menerjemahkannya menjadi timetable yang memutuskan waktu pembuatan dag run. - Pada bawaan Airflow 3, string cron menjadi
CronTriggerTimetableyang menjadikan logical date sama dengan waktu pemicuan run. - Data interval
[mulai, selesai)menyatakan periode data yang diproses, sedangkan pola klasikCronDataIntervalTimetablemembentuknya dari pemicuan sebelumnya hingga pemicuan berikutnya dengan logical date pada batas mulainya. - Catchup tidak aktif secara bawaan pada Airflow 3 melalui konfigurasi
catchup_by_default, berbeda dari bawaanTruepada Airflow 2.x, dan interval yang terlewat diisi melalui backfill.
Referensi#
- Authoring and Scheduling — Apache Airflow
— Gambaran umum parameter
schedulebeserta cara DAG dijadwalkan. - DAGs — Apache Airflow — Definisi logical date serta kaitannya dengan data interval pada dag run.
- Timetables — Apache Airflow
— Uraian timetable dan varian
CronDataIntervalTimetableuntuk jadwal cron.