Start Here
Your shop runs one DAG every day. Its name is shop_orders_daily.
A DAG is a set of tasks with an order. This one has two tasks: load_orders and build_daily_revenue.
You have seen Airflow from the outside. Orchestration & Scheduling taught what an orchestrator does. Scheduling, Data Intervals & the Logical Date Trap taught when a run starts.
Monitoring, Logging, Alerting & Production Failures named some parts of Airflow. This chapter opens the machine and follows one run through every part.
You answer three questions:
- Which part does which job?
- Where is the state kept?
- What happens when a part stops?
The run reads orders from these six. The run about 2026-01-20 reads order 105 and starts on 2026-01-21 00:00:
| id | customer_id | status | amount | order_date |
|---|---|---|---|---|
| 101 | 1 | paid | 40.00 | 2026-01-03 |
| 102 | 1 | paid | 25.00 | 2026-01-10 |
| 103 | 2 | refunded | 60.00 | 2026-01-11 |
| 104 | 3 | paid | 15.50 | 2026-01-15 |
| 105 | 3 | pending | NULL | 2026-01-20 |
| 106 | 4 | paid | 80.00 | 2026-01-21 |
All times, ids and host names in this chapter are made up. Here is the DAG file. It is where the whole journey starts:
import pendulum
from datetime import timedelta
from airflow import DAG
from airflow.operators.python import PythonOperator
from airflow.timetables.interval import CronDataIntervalTimetable
def load_orders():
... # copy one day of orders
def build_daily_revenue():
... # rebuild one day of daily_revenue
with DAG(
dag_id="shop_orders_daily",
schedule=CronDataIntervalTimetable("0 0 * * *", timezone="UTC"),
start_date=pendulum.datetime(2026, 1, 1, tz="UTC"),
catchup=False,
default_args={"retries": 2, "retry_delay": timedelta(minutes=5)},
) as dag:
load = PythonOperator(task_id="load_orders", python_callable=load_orders)
build = PythonOperator(task_id="build_daily_revenue", python_callable=build_daily_revenue)
load >> build