Airflow DAGs

A DAG (Directed Acyclic Graph) is the core building block of Apache Airflow. Every workflow you create in Airflow is a DAG. This topic explains what a DAG is, how to write one, and how Airflow uses it.

What Does "DAG" Mean in Plain English?

Break the term into three words:

  • Directed: Tasks run in a specific direction — from start to finish. Task B cannot start before Task A finishes.
  • Acyclic: There are no loops. A task cannot circle back and trigger an earlier task. The workflow always moves forward.
  • Graph: The workflow is a network of connected tasks drawn as a diagram.

The Recipe Analogy

Think of baking a cake. You must follow steps in order:

[Mix Batter] → [Pour Into Pan] → [Bake in Oven] → [Apply Frosting]

You cannot apply frosting before baking. You cannot bake before mixing. The recipe is a DAG — directed (in order), acyclic (no going back), and a graph (connected steps).

Your First DAG in Python

Create a file called my_first_dag.py inside the ~/airflow/dags/ folder:

from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime

def greet():
    print("Hello from Task 1!")

def farewell():
    print("Goodbye from Task 2!")

with DAG(
    dag_id="my_first_dag",
    start_date=datetime(2024, 1, 1),
    schedule="@daily",
    catchup=False,
) as dag:

    task1 = PythonOperator(
        task_id="say_hello",
        python_callable=greet,
    )

    task2 = PythonOperator(
        task_id="say_goodbye",
        python_callable=farewell,
    )

    task1 >> task2

Breaking Down the Code Line by Line

The Imports

from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime

You import the DAG class to define the workflow, PythonOperator to run Python functions as tasks, and datetime to set the start date.

The Python Functions

def greet():
    print("Hello from Task 1!")

def farewell():
    print("Goodbye from Task 2!")

These are the actual jobs your tasks will perform. They are plain Python functions.

The DAG Definition Block

with DAG(
    dag_id="my_first_dag",
    start_date=datetime(2024, 1, 1),
    schedule="@daily",
    catchup=False,
) as dag:
ParameterPurpose
dag_idUnique name for the DAG shown in the UI
start_dateThe first date the DAG becomes eligible to run
scheduleHow often the DAG runs (@daily, @hourly, cron string, etc.)
catchupFalse = do not run missed past schedules; True = run them all

Setting Task Order With >>

task1 >> task2

The >> operator sets dependency. It means "task1 must finish before task2 starts." You can read it as "task1 flows into task2."

DAG with Branching Tasks

Not all DAGs run in a straight line. Some workflows branch based on conditions:

                  [check_stock]
                 /             \
        [reorder_items]    [send_ok_report]

If stock is low, the left branch runs. If stock is fine, the right branch runs. In code:

check_stock >> [reorder_items, send_ok_report]

You can also write:

check_stock >> reorder_items
check_stock >> send_ok_report

Both lines produce the same branched structure.

Key DAG Parameters You Will Use Often

default_args

Use default_args to apply the same settings to every task in the DAG without repeating them:

default_args = {
    "owner": "data_team",
    "retries": 2,
    "retry_delay": timedelta(minutes=5),
    "email_on_failure": True,
    "email": ["team@example.com"],
}

with DAG(dag_id="sales_dag", default_args=default_args, ...) as dag:
    ...

catchup

If you create a DAG today with a start_date one month ago and catchup=True, Airflow will try to run the DAG for every missed day over the past month. Set catchup=False for most use cases to avoid this.

tags

Tags let you filter DAGs in the UI. Useful when you have dozens of DAGs:

with DAG(dag_id="sales_dag", tags=["sales", "daily"], ...) as dag:

How Airflow Reads Your DAG File

~/airflow/dags/
       │
       ▼
  Airflow Scheduler scans this folder every 30 seconds
       │
       ▼
  Finds my_first_dag.py
       │
       ▼
  Parses (reads) the Python file
       │
       ▼
  Registers "my_first_dag" in the database
       │
       ▼
  Shows it in the UI

Airflow does not run your Python file when the DAG triggers. It parses the file at load time to understand the structure, then executes each task function individually when the schedule fires.

Common DAG Mistakes and Fixes

MistakeSymptomFix
Import error in DAG fileDAG shows "Import Error" in UICheck your Python imports and syntax
Duplicate dag_idOnly one DAG appearsEach DAG needs a unique dag_id
catchup=True on old start_dateHundreds of runs queue up instantlySet catchup=False or set start_date to today
Code runs at module levelSlow DAG loading, UI lagsMove heavy code inside task functions, not at the top level

Leave a Comment

Your email address will not be published. Required fields are marked *