crontool
Paste a schedule, read it in English, see the next runs.

Airflow schedule_interval (Cron)

Airflow DAGs accept a standard five-field cron string for schedule (schedule_interval in older versions), or a preset such as @daily. A key quirk: Airflow runs a DAG at the END of each interval, so a @daily DAG for a given day runs the next midnight.

Setting the schedule

In the DAG: schedule="0 0 * * *" (or schedule_interval pre-2.4). Presets also work: @daily, @hourly, @weekly. Every 15 minutes: */15 * * * *.

The end-of-interval rule

Airflow triggers a run after the interval completes. A @daily DAG with data_interval of 2026-10-01 actually executes at 2026-10-02 00:00. The logical/execution date is the start of the interval, not the wall-clock run time.

start_date and catchup

Runs begin after start_date. If catchup=True (older default), Airflow backfills every missed interval since start_date — set catchup=False to only run going forward.

FAQ

Does Airflow use standard cron for schedule_interval?

Yes — a 5-field cron string, or presets like @daily, @hourly, @weekly. Newer Airflow uses the 'schedule' parameter.

Why does my Airflow @daily DAG run a day late?

Airflow runs at the end of each interval. The run for 2026-10-01 fires at 2026-10-02 00:00; the execution date marks the interval start, not the run time.

How do I stop Airflow backfilling old runs?

Set catchup=False on the DAG so it only schedules runs going forward from start_date instead of filling every missed interval.