Estimated reading time: ~12 minutes. No prior experience required.
By the end of this post you’ll know what Airflow is, why people love it, how to write your first workflow, the mistakes almost everyone makes, and, the fun part, how AI and agents are changing the way we build these pipelines.
What is Airflow, really?
Here’s the one-sentence version: Airflow is a tool that lets you describe your workflows as code, then schedules them, runs them in the right order, retries them when they fail, and shows you exactly what happened.
The orchestra analogy
Think of an orchestra. You’ve got violins, drums, a trumpet, and a flute. Each musician is talented, but if they all just play whenever they feel like it, you get noise, not music. The conductor doesn’t play any instrument, their entire job is timing and coordination. They make sure the violins come in after the intro, the drums hit on the beat, and if someone misses a note, the show still goes on.
Airflow is that conductor for your data and automation tasks. Your individual scripts are the musicians. Airflow makes sure they play in the right order, at the right time, and it notices when one of them messes up.
The “smart to-do list” analogy
If orchestras aren’t your thing, here’s another one. Imagine a to-do list where:
- Some items can only start after others finish (“mail the invoice” depends on “print the invoice”).
- The list runs itself every morning at 6 a.m.
- If a task fails, it politely tries again a few times before giving up.
- You get a dashboard showing which items are done, running, or stuck.
That self-running, dependency-aware to-do list is Airflow.
The core concepts (the whole vocabulary)
Airflow has its own words. Let’s learn them, there are only a handful and they’re not scary.
DAG (Directed Acyclic Graph)
Don’t let the math term intimidate you. A DAG is just a picture of your workflow: boxes (tasks) connected by arrows (dependencies), where the arrows never loop back on themselves.
- Directed = the arrows point one way (“do this, then that”).
- Acyclic = no loops (task A can’t depend on task B if B already depends on A, otherwise you’d wait forever).
- Graph = boxes and arrows.
In Airflow, one DAG = one workflow. Here’s a classic “ETL” (Extract, Transform, Load) DAG:
flowchart LR
A[Extract: pull raw data] --> B[Transform: clean & reshape]
B --> C[Load: save to warehouse]
C --> D[Notify: send success email]
Enter fullscreen mode Exit fullscreen mode
Task
A task is a single box in that diagram, one unit of work. “Download the file” is a task. “Clean the data” is a task. Tasks are the things Airflow actually runs.
Operator
An operator is a template for a task. Instead of writing the plumbing to run a Python function or a SQL query or a Bash command from scratch, you use a ready-made operator:
-
PythonOperator/@task, run Python code. -
BashOperator, run a shell command. -
SQLExecuteQueryOperator, run SQL against a database. - Hundreds more exist for cloud services, APIs, and databases.
Think of operators as LEGO bricks. You snap them together to build a workflow instead of molding every piece by hand.
Scheduler
The scheduler is the part of Airflow that’s always awake, watching the clock. When it’s time for a DAG to run (say, 6 a.m. daily), the scheduler kicks it off. This is the conductor raising the baton.
Executor and workers
Deciding what to run is one thing; actually running it is another. The executor is Airflow’s strategy for running tasks, sometimes one at a time on a single machine, sometimes hundreds in parallel across a cluster. The workers are the machines/processes that do the actual labor.
XCom (cross-communication)
Sometimes one task needs to hand a small piece of data to the next task, like passing a note. XCom is that note-passing mechanism. Task A can push a value (“I processed 4,271 rows”), and Task B can pull it. Keep the notes small, XCom is for little messages, not for shipping gigabytes.
Retries
Because the real world is flaky (networks blip, APIs time out), Airflow lets any task say “if I fail, try me again up to 3 times, waiting 5 minutes between attempts.” This single feature would have saved me that 2 a.m. phone call.
Let’s actually build one
Enough theory. Here’s a complete, minimal Airflow DAG using the modern, readable style. Save this as a .py file in your Airflow dags/ folder.
from __future__ import annotations
import pendulum
from airflow.decorators import dag, task
@dag(
schedule="0 6 * * *", # every day at 6:00 AM (cron syntax)
start_date=pendulum.datetime(2024, 1, 1, tz="UTC"),
catchup=False, # don't back-fill old missed runs
default_args={
"retries": 3, # try failed tasks 3 more times
"retry_delay": pendulum.duration(minutes=5),
},
tags=["tutorial"],
)
def daily_sales_report():
@task
def extract() -> list[dict]:
# Pretend we pulled these rows from a source system.
return [
{"item": "coffee", "amount": 4},
{"item": "tea", "amount": 2},
{"item": "coffee", "amount": 1},
]
@task
def transform(rows: list[dict]) -> dict:
totals: dict[str, int] = {}
for row in rows:
totals[row["item"]] = totals.get(row["item"], 0) + row["amount"]
return totals
@task
def load(totals: dict) -> None:
# In real life you'd write to a database or file.
print(f"Final totals: {totals}")
# This line defines the dependencies (the arrows in the DAG).
load(transform(extract()))
daily_sales_report()
Enter fullscreen mode Exit fullscreen mode
A few things worth pointing out:
- The
@dagdecorator turns a plain Python function into a whole workflow. - Each
@taskis a box in the graph. - The last line,
load(transform(extract())), is where the magic happens. By passing the output of one task into the next, Airflow automatically figures out the order: extract โ transform โ load. You never draw the arrows manually; the code is the diagram. -
schedule="0 6 * * *"is cron syntax. It reads right-to-left-ish as “minute 0, hour 6, every day.” If cron looks like a cat walked across your keyboard, don’t worry, there are free websites that translate it into plain English.
What “running” looks like
Once this file is in your dags/ folder, Airflow’s web interface shows your DAG. You can:
- See a grid of every run, color-coded (green = success, red = failed, yellow = running).
- Click any task to read its logs.
- Manually trigger a run, or re-run just the failed part.
That visibility is the whole point. No more flashlight-in-the-log-file archaeology.
A realistic mini walk-through
Let’s say you run an online store and every morning you want a “yesterday’s revenue” report. Your DAG might look like:
flowchart LR
A[Pull orders from database] --> B[Pull refunds from API]
A --> C[Calculate gross revenue]
B --> C
C --> D[Subtract refunds = net revenue]
D --> E[Write report to spreadsheet]
D --> F[Post summary to team chat]
Enter fullscreen mode Exit fullscreen mode
Notice that “Calculate gross revenue” waits for both the orders and the refunds to be ready, Airflow handles that “wait for multiple things” logic for you. And the final report and chat message can happen in parallel because neither depends on the other. You describe what depends on what, and Airflow works out the timing.
Common mistakes and gotchas
I’ve made every one of these. Learn from my scars.
1. Tasks that aren’t idempotent
Idempotent is a fancy word meaning “running it twice gives the same result as running it once.” Because Airflow retries tasks, a task that appends “sold 10 coffees” every time it runs will double- or triple-count on retry. Design tasks so that re-running them is safe, for example, replace yesterday’s data instead of adding to it.
2. Doing heavy work at the top of the file
Airflow re-reads your DAG file constantly to keep the schedule fresh. If you put a slow database query or a big file download outside of a task (at the top level of the file), Airflow runs that slow thing over and over just while parsing. Keep the top of the file light; put real work inside tasks.
3. Confusing “schedule time” with “run time”
Airflow has a famous quirk: a DAG scheduled @daily for January 1st actually runs at the end of that day/period. The “logical date” (what the run represents) and the wall-clock time it fires are different things. Beginners lose hours here. Just know it exists, and read the run’s logical date rather than assuming “it ran today, so it’s today’s data.”
4. Stuffing big data through XCom
XCom is for small notes. If you push a giant DataFrame through it, you’ll bloat Airflow’s database and slow everything down. Instead, save big data to a file or table and pass the location (“s3://bucket/2024-01-01.csv”) through XCom.
5. Timezone surprises
Always set an explicit timezone (like UTC) in your start_date. Leaving it fuzzy leads to jobs firing an hour early or late, especially around daylight-saving changes.
Using AI and agents with Airflow
This is where things get genuinely exciting. Airflow is code, and AI is very, very good at helping with code. Here are practical, real ways people use AI today.
1. Turn plain English into a DAG
You can describe a workflow conversationally to an AI coding assistant:
“Create an Airflow DAG that runs every weekday at 7 a.m., pulls data from an API, cleans it, writes it to a database table, and emails me if it fails. Add 3 retries.”
A good assistant will scaffold the entire DAG, decorators, schedule, retries, task functions, in seconds. You review, tweak, and ship. Your job shifts from typing boilerplate to reviewing and deciding.
2. Explain a failing task from its logs
When a task turns red, you can paste the traceback and the task code into an AI assistant and ask, “Why did this fail and how do I fix it?” Instead of Googling a cryptic error, you get a plain-English diagnosis: “Your API returned a 429, that’s rate limiting. Add a longer retry_delay or a backoff.” This is the single biggest time-saver for beginners.
3. Suggest better structure and dependencies
Paste an existing messy DAG and ask, “Are there tasks here that could run in parallel?” or “Is anything here not idempotent?” AI is good at spotting the gotchas listed above before they page you at 2 a.m.
4. Agents that fix pipelines automatically
The frontier right now is agents, AI systems that don’t just answer questions but take actions. Imagine an agent connected to your Airflow instance that:
- Notices a DAG failed.
- Reads the logs, identifies the root cause.
- Writes a proposed code fix.
- Opens a pull request for a human to approve.
You stay in control (a human approves the change), but the tedious detective work is done for you. Teams are wiring these up today using Airflow’s APIs plus an AI agent framework.
5. Generate tests and documentation
Ask an assistant to “write a test that checks my transform task handles empty input” or “add clear docstrings to every task.” Coverage and documentation, the stuff we all skip when busy, become one-line requests.
A word of caution: AI-generated pipelines can look perfect and still be subtly wrong. Always review, always test on non-critical data first, and never let an agent touch production without a human approval step. AI is a brilliant co-pilot, not an unsupervised replacement.
Wrapping up
Airflow takes the messy, error-prone job of “run these things in the right order, on time, and tell me when something breaks” and turns it into clean, versionable, visible code. You learned:
- What it is: a conductor / self-running to-do list for your tasks.
- The vocabulary: DAGs, tasks, operators, the scheduler, executors, XCom, retries.
- How to build one: a few decorators and letting the code define the dependencies.
- The classic traps: idempotency, heavy top-level code, schedule-time confusion, XCom bloat, timezones.
- The AI angle: from English-to-DAG generation to self-healing agents.
Where to go next
- Install Airflow locally (the official “quick start” and Docker images make this a coffee-break task) and get that first DAG green.
- Rewrite one thing you currently run “by hand every morning” as a DAG.
- Try describing a workflow to an AI assistant and reviewing what it produces, you’ll learn Airflow’s patterns faster by editing than by staring at a blank file.
The best part? Once your workflows live in Airflow, nobody gets a 2 a.m. phone call. The conductor’s got it.
๐ข Letโs Connect!
๐ผ LinkedIn | ๐ GitHub | โ๏ธ Dev.to | ๐ Hashnode
๐ก Join the Conversation:
- Found this useful? Like ๐, comment ๐ฌ
- Share ๐ to help others on their journey
- Have ideas? Share them below!
- Bookmark ๐ this content for easy access later
Letโs collaborate and create something amazing! ๐
๋ต๊ธ ๋จ๊ธฐ๊ธฐ