An open-source platform to programmatically author, schedule, and monitor workflows, commonly used for orchestrating data pipelines and ETL jobs.
Apache Airflow is the elder statesman of modern workflow orchestration. Created at Airbnb in 2014, donated to Apache, and now running more production data pipelines than any other tool in the category. When someone says "we orchestrate our data pipelines," Airflow is the default assumption — to the point that teams often pick it reflexively without evaluating newer alternatives like Dagster, Prefect, or cloud-native offerings (AWS Step Functions, GCP Workflows, Temporal).
Airflow is an orchestrator, not an ETL tool. It schedules tasks, manages dependencies between them, retries on failure, logs execution history, and provides a web UI for monitoring. It does not move data, transform data, or connect to data sources by itself — that's the job of the tasks it runs (typically Python operators, Bash operators, or provider-specific operators for dbt, Snowflake, Spark, etc.). This distinction matters when teams get confused about why Airflow is slow (it's usually not Airflow — it's the tasks Airflow is running).
A client's Airflow deployment had grown to 800 DAGs on a single self-hosted instance, parsing every DAG file every 30 seconds. The scheduler was spending 60% of its time just parsing Python, and DAG start latency had climbed to 12 minutes. Three fixes in sequence: (1) enabled dag_discovery_safe_mode and moved DAG imports to lazy-load patterns, cutting parse time 70%; (2) moved the heavy-transformation DAGs to KubernetesExecutor so scheduler load dropped; (3) finally sharded into two Airflow deployments by team. After the work, DAG start latency was under 30 seconds and the scheduler CPU sat at 15%. Lesson: Airflow scales, but you have to actively manage the scheduler — it won't warn you when you're approaching its limits, you'll just notice everything gradually getting slower.
Apache Airflow is an open-source workflow orchestration platform created at Airbnb and now maintained by the Apache Software Foundation. It allows you to define, schedule, and monitor complex data workflows as code.
from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime
with DAG('my_etl_dag', start_date=datetime(2024, 1, 1), schedule='@daily') as dag:
extract = PythonOperator(task_id='extract', python_callable=extract_data)
transform = PythonOperator(task_id='transform', python_callable=transform_data)
load = PythonOperator(task_id='load', python_callable=load_data)
extract >> transform >> load| Tool | Strength | Best For |
|---|---|---|
| Airflow | Flexibility, ecosystem | Complex custom workflows |
| Prefect | Python-native, cloud-first | Modern data apps |
| Dagster | Software-defined assets | Data platform teams |
| dbt Cloud | SQL transformations | Analytics engineering |
Airflow pitfalls I've watched teams rediscover:
start_date and schedule_interval semantics confuse everyone. A DAG with start_date=2024-01-01 and @daily schedule runs at the end of each interval — the first run fires at 2024-01-02 00:00 for the 2024-01-01 interval. Teams lose hours debugging "why isn't my DAG running yet?" Read the data-interval docs carefully before scheduling anything.max_active_runs, pool limits, and depends_on_past=True to throttle. A 3 AM backfill that consumed all the Snowflake credits for a small customer is a real war story.sql_alchemy_pool_size, sql_alchemy_max_overflow, and Postgres max_connections together. Surprise connection-exhaustion outages are common.retries=0.catchup=True is the default and causes chaos. When you deploy a DAG with an old start_date, Airflow fires runs for every missed interval. Always set catchup=False unless you explicitly want historical backfill on deployment.Airflow is used to orchestrate complex workflows — most commonly data pipelines (ETL/ELT), but also ML training/deployment, report generation, and periodic maintenance jobs. You define workflows as Python code (DAGs), specify task dependencies, and Airflow schedules tasks, handles retries, logs execution history, and provides a web UI for monitoring. It's the coordination layer that tells dbt to run after Fivetran completes, then tells Tableau to refresh after dbt succeeds, then alerts PagerDuty if anything fails. Popular both as self-hosted OSS and as managed services (Astronomer, AWS MWAA, Google Cloud Composer).
No — Airflow is an orchestration tool, not an ETL tool. It schedules and monitors tasks but does not extract, transform, or load data itself. The tasks you run inside Airflow (Python functions, dbt commands, Spark jobs, Snowflake queries) do the actual data work. This is a common confusion: new users expect Airflow to have built-in connectors like Fivetran or a SQL transformation engine like dbt. It doesn't — Airflow's value is in coordinating those tools, not replacing them. The modern stack typically pairs Airflow (orchestration) with Fivetran or Airbyte (ingestion) and dbt (transformation).
A DAG (Directed Acyclic Graph) is Airflow's representation of a workflow. "Directed" means tasks have specified execution order; "Acyclic" means no task can loop back to a previous task (preventing infinite loops). A DAG file is Python code defining tasks and their dependencies using operators like `>>` for downstream. Example: `extract >> transform >> load` makes transform run after extract finishes and load run after transform finishes. DAGs are parameterized by `start_date`, `schedule`, default args, and other settings that control how Airflow executes them over time.
Apache Airflow itself is 100% free and open-source (Apache 2.0 license) — you can self-host it with no licensing costs. The commercial layer comes from managed services: Astronomer ($$$, feature-rich developer experience), AWS MWAA (pay for underlying infrastructure + management fee), Google Cloud Composer (GCP-native managed Airflow), Azure Data Factory has a managed Airflow option. Self-hosting is cheapest in license cost but expensive in operational cost (running the scheduler, tuning the metadata DB, handling upgrades). Most teams past 20-30 DAGs benefit from a managed service.
Airflow: oldest and most-adopted; huge provider ecosystem; Python-native but some operators feel bolt-on; scheduler-centric model. Prefect: Python-native with cleaner dataflow semantics; cloud-first design; uses "flows" instead of DAGs. Dagster: software-defined assets approach (declare the outputs, not the tasks); stronger typing; better dev experience for new teams. For mature data orgs with existing Airflow investment, migrating is rarely worth it. For greenfield projects, Dagster and Prefect have meaningfully better developer experience. All three cover the same core use cases; choose based on team preference and ecosystem fit.
Several dials: (1) switch from SequentialExecutor/LocalExecutor to CeleryExecutor or KubernetesExecutor for distributed task execution; (2) run multiple schedulers (HA mode, since 2.0); (3) shard the metadata database on a dedicated high-memory Postgres instance; (4) reduce DAG parse overhead via lazy imports and `dag_discovery_safe_mode`; (5) use pools to bound concurrency to external systems; (6) at very high scale, run multiple Airflow deployments partitioned by team or domain. Beyond ~3000 DAGs per deployment, operational complexity usually justifies moving to a managed service or sharding.
Generally no. Airflow is a batch scheduler — its minimum practical interval is about 1 minute, and it's not designed for event-driven sub-second latencies. For streaming, use Kafka + Flink/Spark Streaming/Kafka Streams, or managed services like AWS Kinesis Data Analytics, Confluent Cloud. Airflow is excellent for *orchestrating* streaming infrastructure (deploying a new Flink job, scheduling a reconciliation batch) but not for the streaming data processing itself. The complementary pattern — Airflow for batch, Kafka+Flink for streaming — is a common architecture.