Airflow 3.0 129 bundled the Task Execution API and Task SDK (AIP-72), DAG versioning (AIP-66), the React 7,897 UI on FastAPI 36,700 (AIP-38, AIP-84), assets and event-driven scheduling (AIP-74, AIP-75), scheduler-managed backfills (AIP-78) and the Edge executor (AIP-69). Later 3.x releases added human-in-the-loop approvals and deadline alerts (3.1), multi-team deployments and asset partitioning (3.2), and a task and asset state store, pluggable retry policies and Java and Go Task SDKs (3.3). The removals are what bite; removed.py tries a few Airflow 2 idioms on 3.3.2:
SubDagOperator ModuleNotFoundError SequentialExecutor ModuleNotFoundError DebugExecutor ModuleNotFoundError DummyOperator ModuleNotFoundError SlaMiss ModuleNotFoundError DAG(schedule_interval=...) TypeError: unexpected keyword argument DAG(timetable=...) TypeError: unexpected keyword argument
| Airflow 2 | Airflow 3 |
|---|---|
| SubDAGs | Task groups |
| SLAs and sla_miss_callback | Deadline alerts |
| schedule_interval=, timetable= | schedule= |
| execution_date in the context | logical_date, data interval |
| BashOperator, PythonOperator in core | apache-airflow-providers-standard |
Defaults changed too: catchup is False, cron schedules no longer create data intervals unless asked (create_cron_data_intervals), the SimpleAuthManager replaced Flask 15,439 AppBuilder (now a provider), and the DAG processor runs on its own. Upgrade from 2.7 or later, and lint first: ruff check dags/ --select AIR301,AIR302 lists breaking uses, and --fix rewrites many imports.