# Core Concepts: DAG, Task, Run, Instance — Apache Airflow: Orchestrate Data Pipelines

Source: https://www.geekswithgeeks.com/en/airflow/af-core-concepts

> Distinguish a DAG definition, a DAG run, a task and a task instance.

## Definition vs execution

A **DAG** is the definition: tasks and their dependencies plus a schedule. A **task** is one unit of work, created from an **operator** (a template such as `BashOperator`) or the `@task` decorator. Each time the DAG is scheduled, Airflow creates a **DAG run**; every task in it becomes a **task instance** with its own state (`queued`, `running`, `success`, `failed`, `skipped`, `up_for_retry`…). A DAG run is identified by its **logical date** (called the data interval in newer terms), which says which slice of time the run is about, not necessarily when it executes.

## A first DAG

Save in the `dags/` folder. This uses Airflow 3 imports (`airflow.sdk`); in Airflow 2 the equivalent imports are `from airflow import DAG` and `from airflow.operators.bash import BashOperator`. `{{ ds }}` is the logical date as YYYY-MM-DD. I ran it with `airflow dags test hello_airflow 2026-10-01` on Airflow 3.0.6 and `say_hello` printed the line below.

```python
from datetime import datetime

from airflow.sdk import DAG
from airflow.providers.standard.operators.bash import BashOperator

with DAG(
    dag_id="hello_airflow",
    start_date=datetime(2026, 9, 1),
    schedule="@daily",
    catchup=False,
    tags=["demo"],
) as dag:
    say_hello = BashOperator(task_id="say_hello", bash_command="echo Hello from {{ ds }}")
    say_bye = BashOperator(task_id="say_bye", bash_command="echo Bye")

    say_hello >> say_bye
```

Output:

```
Hello from 2026-10-01
```

**Quiz:** What is a task instance?

- [ ] The DAG file itself
- [x] One task within one specific DAG run, with its own state
- [ ] The metadata database
- [ ] A worker machine

*Answer:* One task within one specific DAG run, with its own state. A task instance is the runtime record of a task for a particular run.
