Lesson 12 / 25

Branching

Choose one path at run time with @task.branch and rejoin with a suitable trigger rule.

Only one path runs

A branch task returns the task_id (or list of IDs) to follow; all other direct downstream paths are skipped. Use it for decisions such as "is it a weekday?" or "did new data arrive?". The task that rejoins the paths needs a trigger rule like none_failed_min_one_success, because with the default all_success it would be skipped when one of its upstream paths was skipped.

Decide, wait, fan out

Branching, trigger rules, sensors and dynamic mapping let a DAG adapt to the data and the world.

Four tools: branch, rule, wait, map.
Figure 4.1 — Branch, rule, wait and map.

A weekday branch

I ran this on Airflow 3.0.6 with airflow dags test report_branch 2026-10-01. 1 October 2026 is a Thursday, so weekday_report ran, weekend_summary was skipped, and Airflow logged one downstream task skipped. logical_date is available in the task context.

from datetime import datetime

from airflow.sdk import dag, task
from airflow.providers.standard.operators.empty import EmptyOperator

@dag(schedule="@daily", start_date=datetime(2026, 9, 1), catchup=False)
def report_branch():
    @task.branch
    def choose(logical_date=None):
        return "weekday_report" if logical_date.weekday() < 5 else "weekend_summary"

    weekday = EmptyOperator(task_id="weekday_report")
    weekend = EmptyOperator(task_id="weekend_summary")
    done = EmptyOperator(task_id="done", trigger_rule="none_failed_min_one_success")

    choose() >> [weekday, weekend] >> done

report_branch()

Use a clear join task

Always put a join task after branches and give it the right trigger rule. Forgetting this is the classic reason that everything after a branch is mysteriously skipped.

Quick check: What happens to the paths not chosen by a branch task?

  • They run anyway
  • They are skipped
  • They fail
  • They are deleted from the DAG
Answer

They are skipped — Unchosen branches get the skipped state for that run.