This lesson on Airflow in Production — Scheduling, Backfills & Retries is hands-on and example-driven. You will be able to execute targeted historical DAG backfills from the Airflow CLI, diagnose failed execution windows via the web UI, and manage task retry behaviors using state-resetting and rerun flags.
What You'll Be Able To Do
- Configure catchup parameters on DAG definitions to control automatic historical run generation upon unpausing.
- Execute CLI backfills over targeted date ranges using the airflow dags backfill command with start and end flags.
- Diagnose pipeline execution failure intervals using the Airflow UI Dag Runs list and Calendar View.
- Rerun failed task instances within historical execution windows using the --rerun-failed-tasks flag.
- Reset DAG Run states with --reset-dag-runs to enforce configured task retry limits during CLI backfills.
- Accelerate historical reprocessing by bypassing task retries using the --disable-retry flag.
Detailed Concept Walkthrough
1. Automated Catchup vs Manual Backfills
Historical execution intervals are generated automatically by scheduler catchup or manually targeted via CLI backfill commands.
- Mechanism: Setting
catchup=Trueon a DAG configuration instructs the scheduler to create runs for every missing interval betweenstart_dateand current time upon unpausing. - Execution Flow: When processing intervals prior to
start_dateor applying selective reprocessing, manual CLI backfilling bypasses the automatic scheduler queue. - Best Practice: Keep
catchup=Falseas the default in production DAG definitions to prevent accidental execution floods when deploying new pipelines.
from datetime import datetime, timedelta
from airflow import DAG
with DAG(
dag_id="sales_ingest_pipeline",
start_date=datetime(2025, 1, 1),
schedule_interval="@daily",
catchup=False, # Disables automatic historical backlog execution
default_args={"retries": 3, "retry_delay": timedelta(minutes=5)},
) as dag:
pass
Key Takeaway: Automatic catchup runs intervals from start_date upon unpausing, whereas CLI backfilling manually targets custom time windows.
2. Executing CLI Historical Backfills
The Airflow CLI is the required interface for triggering custom backfills across specified historical date bounds.
- Syntax Rule: The
airflow dags backfillcommand requires a DAG ID along with-s(--start-date) and-e(--end-date) flags formatted asYYYY-MM-DD. - Under the Hood: CLI backfills directly create execution jobs tagged with a distinct 'Backfill' run type visible in the Airflow UI.
- Best Practice: Check the Dag Runs list or Calendar View in the web UI first to determine the exact failure dates before formulating CLI parameters.
# Backfill a specific historical date range prior to or within DAG start_date
airflow dags backfill \
--start-date 2025-01-25 \
--end-date 2025-02-05 \
sales_ingest_pipeline
Key Takeaway: Backfills cannot be initiated directly through the web UI and must be run using the Airflow CLI.
3. Task Retries and Failed State Handling
Standard backfill invocations skip already failed runs unless rerun flags are explicitly supplied.
- Mechanism: Every task execution increments its Try Number metadata field until reaching the maximum configured
retriesparameter. - Under the Hood: Running a standard
airflow dags backfillagainst previously executed intervals ignores failed tasks without incrementing the Try Number. - Nuance: Adding
--rerun-failed-tasksforces Airflow to rerun failed tasks, but it only attempts a single execution per failed run attempt.
# Re-execute only the failed tasks across a historical interval (single retry attempt)
airflow dags backfill \
--start-date 2025-01-25 \
--end-date 2025-02-05 \
--rerun-failed-tasks \
sales_ingest_pipeline
Key Takeaway: A standard backfill ignores existing failed tasks unless the --rerun-failed-tasks flag is specified.
4. Resetting DAG Run States and Disabling Retries
Resetting run states restores full task retry counts, whereas disabling retries optimizes backfills by failing immediately.
- Mechanism: The
--reset-dag-runsflag clears existing DAG run state in the metadata database, enabling tasks to use their fullretriesallowance. - Execution Flow: Combining
--rerun-failed-taskswith--reset-dag-runsguarantees that tasks with transient errors retry up to the configured retry limit. - Best Practice: Use
--disable-retryduring high-volume backfills to fail fast on deterministic bugs and prevent long retry delays.
# Option A: Full recovery respecting configured retry counts (e.g., retries=15)
airflow dags backfill -s 2025-01-25 -e 2025-02-05 --rerun-failed-tasks --reset-dag-runs sales_ingest_pipeline
# Option B: Fast-fail optimization bypassing automatic task retries
airflow dags backfill -s 2025-01-25 -e 2025-02-05 --rerun-failed-tasks --disable-retry sales_ingest_pipeline
Key Takeaway: Resetting DAG runs restores full task retry limits, while disabling retries avoids bottlenecks during backfills.
Topics Covered in Airflow in Production — Scheduling, Backfills & Retries
- Backfilling Core Concepts (0:00 - 0:33) — Introduces backfilling as the process of running DAGs or tasks for past, untriggered, or failed intervals.
- Backfill Scenarios and Use Cases (0:33 - 1:15) — Outlines key scenarios requiring backfills including new pipelines, failure handling, logic changes, and selective reruns.
- CLI Backfill Tooling (1:15 - 1:42) — Explains that backfilling is officially executed via the Airflow CLI rather than through the web interface.
- Scheduler Catchup Mechanism (1:42 - 2:24) — Demonstrates enabling catchup=True on a DAG to auto-generate historical runs between start_date and current time.
- Date-Bounded CLI Backfills (2:24 - 4:11) — Executes a CLI backfill using start and end date flags and verifies the Backfill run type indicator in the UI.
- Diagnosing Failed Intervals (4:11 - 5:24) — Identifies failed historical date windows using the Dag Runs table and the Calendar View in the web UI.
- Task Retries and Try Numbers (5:24 - 7:11) — Explains Try Number tracking and shows how standard backfills fail to rerun previously failed tasks.
- Rerunning Failed Tasks (7:11 - 7:54) — Applies the rerun-failed-tasks flag to force a single rerun attempt on failed tasks within the date window.
- Resetting DAG Run States (7:54 - 8:52) — Combines reset-dag-runs with rerun-failed-tasks to reset execution state and enforce full configured task retries.
- Disabling Automatic Retries (8:52 - 9:12) — Introduces the disable-retry flag to bypass task retry delays and optimize backfill execution speed.
Data Engineering Cheat Sheet
-
catchup=True— Auto-generates past runs between start_date and unpause timeDAG(dag_id="orders", start_date=datetime(2025, 1, 1), catchup=True) -
airflow dags backfill -s <START> -e <END> <DAG_ID>— Triggers historical execution for designated date rangeairflow dags backfill -s 2025-01-01 -e 2025-01-07 daily_etl -
--rerun-failed-tasks— Attempts a single rerun of failed tasks in backfill windowairflow dags backfill -s 2025-01-01 -e 2025-01-07 --rerun-failed-tasks daily_etl -
--reset-dag-runs— Resets run metadata allowing full task retry countsairflow dags backfill -s 2025-01-01 -e 2025-01-07 --rerun-failed-tasks --reset-dag-runs daily_etl -
--disable-retry— Disables task retries for faster failing backfill executionairflow dags backfill -s 2025-01-01 -e 2025-01-07 --disable-retry daily_etl
Comparison Table
| Backfill Option | Retry Policy Behavior | Primary Use Case |
|---|---|---|
| Default Backfill | Skips existing runs completely | Generating new untriggered intervals |
| --rerun-failed-tasks | Executes failed tasks once | Single-attempt rerun of failures |
| --reset-dag-runs | Enforces full task retries | Complete rerun with full retry policy |
| --disable-retry | Overrides task retries to zero | Fast-failing backfills during debugging |
Common Pitfalls
- Mistake: Attempting to trigger historical backfills directly through the Airflow web UI. Avoid: Execute the airflow dags backfill command via the CLI using date flags.
- Mistake: Running a basic backfill expecting failed tasks to rerun automatically. Avoid: Provide the rerun-failed-tasks flag to target tasks in a failed state.
- Mistake: Expecting rerun-failed-tasks alone to respect configured retry limits. Avoid: Include reset-dag-runs alongside rerun-failed-tasks to reset state and restore retry counts.
- Mistake: Allowing long retry delays during large historical backfills with broken logic. Avoid: Pass disable-retry to terminate failing tasks immediately without retry waits.
FAQs
- Can I trigger a backfill operation directly from the Airflow web UI? No, official Airflow backfill operations must be executed exclusively through the Command Line Interface (CLI).
- What is the difference between catchup=True and a CLI backfill? Setting catchup=True prompts the scheduler to run all missing intervals since start_date upon unpausing, whereas CLI backfilling manually runs any user-defined date window.
- Why does --rerun-failed-tasks only retry my failing task once despite retries=15? The --rerun-failed-tasks flag only triggers a single attempt; you must also pass --reset-dag-runs to restore the DAG run state and full retry policy.
- How can I locate the exact date bounds of failed runs to backfill? Inspect the Dag Runs list or use the Calendar View in the Airflow UI to find the start and end dates of failed executions.