Apache Airflow vs Dagster

Differences and When Each Fits

Apache Airflow (the workflow orchestrator, not ventilation) and Dagster are both open source data orchestrators. Airflow models a pipeline as tasks that run in order, while Dagster models it as the data assets those tasks produce. Which fits depends on whether your work looks like a chain of jobs or a graph of tables.

Last updated: Proudly published by: Jeff Wahl9 min read

Apache Airflow vs Dagster: what is the difference?

Apache Airflow and Dagster are both open source orchestrators that run data pipelines on a schedule or on an event. Both retry what fails and show run results in a web UI. The core difference is what you declare. Airflow asks you to declare tasks and the order they run in. Dagster asks you to declare the tables and models a pipeline produces, called assets, and works out the runs from how those assets depend on each other.

Neither is better in general, and the right pick depends on the work. Airflow, first released at Airbnb and now an Apache top-level project, has the larger installed base: its repository shows 47.4k stars against 16.4k for Dagster, and the stable docs are at 3.3.2. Both ship under the Apache-2.0 license, so the choice is about fit, not licensing.

Prepare for the interview
01 / Open invite
02min.

Know Airflow vs Dagster the way the interviewer who asks it knows it.

a Airflow vs Dagster query, the same shape a screen would give you.
The diff against expected. Where ties broke. What you missed.
sandbox
1source → bronze → silver → gold
2 ingest : CDC + Kafka
3 transform : dbt + Airflow
4 serve : Snowflake
5
Execute your solution0.4s avg.
GoogleInterview question
Solve a Airflow vs Dagster problem

Task graph vs asset graph: how each tool models a pipeline

An Airflow Dag is a graph of tasks. Each node is a step that runs, such as an extract or a load, and each edge says which step must finish first. The Dag describes how the work is done. What the work produces, such as a table, lives inside the task code and is invisible to the scheduler unless you declare it.

2 rows of 3 linked nodes: Airflow draws the steps that run, extract, transform and load, as tasks; Dagster draws the tables those steps leave behind, raw_orders, orders and sales, as assets2 rows of 3 linked nodes: Airflow draws the steps that run, extract, transform and load, as tasks; Dagster draws the tables those steps leave behind, raw_orders, orders and sales, as assets

A Dagster project is a graph of assets. Each node is a thing that exists after the run: a table, a file, a model. An edge says one asset is built from another, so the graph is also the lineage. The Dagster docs define an asset as a logical unit of data and note that assets have largely replaced ops, the older unit of computation.

The consequence shows up when something breaks. A task graph answers which step failed. An asset graph answers which table is stale and which tables downstream of it are affected. Airflow can answer the second question too when assets are declared, and Dagster still has jobs for work that is not asset-shaped, which run on schedules or sensors, so the 2 models overlap more every year.

The same 3 step pipeline written for each tool

PYorders_pipeline.py
from airflow.sdk import dag, task
import pendulum


@dag(schedule="@daily", start_date=pendulum.datetime(2026, 1, 1, tz="UTC"), catchup=False)
def orders_pipeline():
    @task
    def extract():
        return {"rows": 1200}

    @task
    def transform(raw):
        return {"rows": raw["rows"]}

    @task
    def load(clean):
        print(clean["rows"])

    load(transform(extract()))


orders_pipeline()

The TaskFlow API: calling a task with another task's result sets the order, and Airflow passes the value through XCom

What the code shows about authoring in each tool

Both versions are plain Python. In Airflow, @dag carries the start date and a schedule with its catch-up policy, and the tasks sit inside it. Order comes from calling one task with another's return value. Airflow stores that returned value through XCom, its mechanism for passing small values between tasks, so large datasets still belong in external storage, with the task passing a path or a key.

In Dagster, the @dg.asset function is the unit, and its name is the asset's name. A parameter called raw_orders tells Dagster this asset depends on the asset of that name, which makes the dependency graph part of the function signature. Where an asset needs another asset to exist but does not read its value, deps=[...] declares the dependency without passing data. Nothing in the file says when it runs: schedules and sensors are attached separately, along with partitions, so the same asset can be rebuilt on a cron or an event, or run by hand.

Airflow and Dagster on the same criteria

Apache Airflow
  • Core unitTask in a Dag
  • DependenciesTask order
  • Data-triggered runsAssets, since 2.4
  • Services to runScheduler and workers
  • LicenseApache-2.0
  • GitHub stars47.4k
Dagster
  • Core unitAsset
  • DependenciesAsset lineage
  • Data-triggered runsSensors and assets
  • Services to runWebserver and daemon
  • LicenseApache-2.0
  • GitHub stars16.4k

Scheduling, assets and event-driven runs

Airflow began with time-based schedules and has added data-aware ones. Asset-aware scheduling arrived in 2.4: a producer task lists an asset as an outlet, and a consumer Dag names that asset in its schedule. The Airflow asset scheduling docs add 2 details that matter in practice. An asset counts as updated only when the producing task succeeds, and a consumer waiting on several assets runs once all of them have updated since its last run. Expressions built with & and | combine them.

Airflow April 22, 2025 brought 3.0, which the project's release post describes as adding event-driven scheduling from outside systems, DAG versioning so a run finishes on the version it started with, and backfills run by the scheduler and started from the UI or API. External events arrive by REST push or by an asset watcher that polls a source.

Dagster puts the asset first and the trigger second. A schedule runs assets at an interval, a sensor triggers them when an external event occurs, such as a file landing, and both can carry run configuration. Because the asset is the primary object, the UI can show for every table when it was last built and what it was built from, without extra declarations.

Partitions, backfills and data checks

Reprocessing history is where the models differ most in daily use. In Dagster, a partition is a slice of an asset, usually a time window. Attach partitions_def=DailyPartitionsDefinition(start_date=...) to an asset and the run reads context.partition_key to know which day it is building. The docs recommend keeping each asset to 100,000 partitions or fewer for the UI to stay responsive, and multi-partition runs need the daemon running to queue them.

In Airflow, each Dag run carries a data interval and a task reads its logical date to know which slice to build. Before 3.0, backfills were started from the command line. Since 3.0 the scheduler runs them. Either way, the discipline that makes a backfill safe is the same in both tools: write each run so that rerunning a day replaces that day instead of appending to it, which is the idempotency property data engineering interviews test.

Dagster's asset checks add data quality tests to the asset itself. A check decorated with @dg.asset_check runs after the asset is materialized, and by default a failed check does not stop downstream assets unless it is marked blocking=True. In Airflow, the equivalent is a task you place in the Dag, or an external tool such as a data quality framework that you call from a task.

Deploying and operating each orchestrator

Airflow runs as a set of services around a metadata database. The scheduler is a persistent service, and running more than 1 is supported on PostgreSQL 12+ and MySQL 8.0+. Work runs on an executor. The executor docs list Local as the default and also Celery, Kubernetes, Edge, ECS and Batch executors, and since 2.10 you can configure several at once and choose per task or per Dag.

Dagster's open source deployment has 3 long-running pieces: a webserver for the UI and GraphQL queries, a daemon that runs schedules and sensors and queues runs, and a code location server for each project of definitions. The webserver can have replicas. The daemon cannot, and each code location gets 1 server, which is worth knowing before you promise high availability. The executor and run launcher are swappable, and the default SQLite run storage is normally swapped for Postgres in production.

Code locations are the operational idea Dagster leans on: each team ships its own definitions as a separate deployable, so 1 team's dependency upgrade does not break another's. Airflow reaches the same isolation through separate deployments, per-task containers on the Kubernetes executor, or the Task SDK in 3.0, which separates the code a task runs from the Airflow core.

When Apache Airflow fits

Airflow fits when the work is a set of jobs more than a set of tables. Running a nightly export, a model training job, a call to a vendor API and a cleanup in a fixed order is naturally a Dag of tasks. Airflow's operators and providers cover a large number of systems out of the box.

It fits when you already run it. Existing Dags and shared operators are an asset of their own, as are runbooks and on-call knowledge, and Airflow 3 added scheduler-run backfills, DAG versioning and asset-based triggers, so some of the reasons teams look elsewhere have been addressed inside it. It also fits when hiring or interviewing matters: Airflow knowledge is the more common requirement, and the Airflow interview questions cover what candidates are asked.

When Dagster fits

Dagster fits when the pipeline is mostly tables and models and the questions people ask are about the data: what is stale, what feeds this dashboard, what must rebuild if this source changes. Because assets and their dependencies are the primary objects, the definitions already give you lineage, freshness and partition status without extra bookkeeping.

It fits when you start fresh and want local development and testing to be a first-class path: assets are plain functions that can be called in a test, and resources make external connections a swappable parameter. It also fits teams with many partitioned datasets, where seeing which days are built and rebuilding a range from the UI is a daily task.

Migrating from Airflow to Dagster, or running both

Switching orchestrators does not have to be a rewrite. Dagster's dagster-airlift connects to Airflow's REST API, loads each Airflow Dag into Dagster as an asset definition and adds a sensor that polls Airflow for execution history. In its observe stage you map Airflow Dag and task IDs to the Dagster definitions they produce, with no change to the Airflow code.

In the migrate stage you move execution of individual tasks to Dagster assets in any order, and Airflow proxies each migrated task to Dagster. The task-level migration tutorial in the Dagster docs notes that you can roll a task back by changing a single line in the Airflow Dag, and recommends writing acceptance tests in Dagster before moving a task. This path also suits teams that want Dagster's asset view over an Airflow estate they have no plan to retire.

The other direction has no equivalent tool in the docs reviewed for this page, so a move from Dagster to Airflow is a rewrite of the orchestration layer, with the data transformations themselves usually reusable.

Orchestration in data engineering interviews

Interviewers rarely care which tool you picked. They ask how you would keep a pipeline correct when runs fail, and when they arrive late or repeat: how you make a task idempotent, how you backfill 30 days without double counting, what you alert on and how you order dependencies. Those answers are the same in both tools, and naming the Airflow or Dagster feature that implements each one makes them concrete.

Practice the design questions in the data pipeline interview questions, build the pipelines yourself in the data pipeline practice problems, and rehearse explaining a scheduler choice for the system design round. For more tools in the same space, see data orchestration tools, the Airflow DAG guide and dbt vs Airflow.

Airflow vs Dagster FAQ

What is the main difference between Airflow and Dagster?+
Apache Airflow models a workflow as a Dag of tasks that run in a set order, and Dagster models it as a graph of assets, which are the tables and files the pipeline produces. In Airflow the unit you declare is a step. In Dagster it is the data that step leaves behind.
Is Dagster a replacement for Airflow?+
Both are open source orchestrators under the Apache-2.0 license, and both handle scheduling and retries and ship a UI. Many teams run them side by side while migrating, and Dagster publishes dagster-airlift to observe Airflow Dags and move them task by task. Whether to move depends on how much of your work is asset-shaped and how much of it already runs well.
Does Airflow have assets like Dagster?+
Yes. Airflow added asset-aware scheduling in 2.4, so a Dag can be scheduled on the update of an asset a producer task declares as an outlet, and Airflow 3 added event-driven scheduling from external systems. The difference is the starting point: in Airflow the asset is something a task updates, while in Dagster the asset is the thing you define and the compute hangs off it.
Which is easier to learn, Airflow or Dagster?+
It depends on what you already know. Airflow's TaskFlow API reads like plain Python functions chained by calls, and its core concepts, the Dag and the operator, are widely documented. Dagster asks you to think in assets and resources first, which is a shift for teams used to task chains and pays off when lineage and partitions matter.
Can Airflow and Dagster run together?+
Yes. Dagster's dagster-airlift reads Airflow's REST API to load Airflow Dags into Dagster as assets and a sensor that polls execution history, with no change to the Airflow code. You can then migrate tasks 1 at a time and roll a task back by changing a single line in the Airflow Dag.
Which one do data engineering interviews ask about?+
Airflow questions are far more common in interviews because of its long installed base, and they cover Dags, scheduling, and how retries and backfills behave with idempotent tasks. Orchestration concepts transfer: a candidate who can explain task ordering and backfill safety can answer for either tool.
02 / Why practice

The candidate who gets the offer

  1. 01

    Reading a solution is not the same as writing one

    Every engineer who has frozen on a query they had read a dozen times knows the gap. The only preparation that closes it is producing the answer yourself, under time, before the interview does it for you

  2. 02

    76% of hiring managers reject on the coding task, not the resume

    From HackerRank's 2024 Developer Skills Report. Candidates who look strong on paper still fail the live screen if they haven't done timed, executable practice

  3. 03

    System design comes down to the calls you defend out loud

    Ingestion, batch vs streaming, the bronze/silver/gold layers, idempotency, backfill and replay. Sketching the pipeline and naming the failure modes is the signal, not the boxes

Related guides