Quick verdict
Choose Apache Airflow if your work is best described as a sequence of tasks, if you want a managed service from AWS, Google Cloud or Astronomer, or if your team already runs Airflow; Airflow 3 added asset-aware scheduling and an @asset decorator, which narrows the gap. Choose Dagster if you think in terms of the data assets a pipeline produces and want lineage, materialisation history and asset-level automation at the centre of the tool, and if Dagster+ (or self-hosting) suits you as the control plane.
Apache Airflow is an Apache Software Foundation project for authoring, scheduling and monitoring workflows as DAGs (directed acyclic graphs) of tasks written in Python. Airflow 3.0 was first released on 22 April 2025; the current release is 3.3.2 (17 September 2026). Airflow 3 renamed the concept previously called a dataset to an asset: the Airflow documentation states "Changed in version 3.0: The concept was previously called 'Dataset'", and the upgrade guide maps airflow.datasets.Dataset to airflow.sdk.Asset. Airflow 2.x reached end of life on 22 April 2026.
Dagster, developed by Dagster Labs, describes itself on PyPI as "a cloud-native data pipeline orchestrator for the whole development lifecycle, with integrated lineage and observability, a declarative programming model". Its central abstraction is the software-defined asset: a Python function decorated with @dg.asset that produces a table, file or model, with dependencies between assets forming a lineage graph. Dagster also supports ops and jobs for task-style work. The current release is 1.13.25 (1 October 2026), supporting Python 3.10 to 3.14. Dagster+ is the vendor's hosted platform.
Both are orchestrators, not connector-based ingestion tools. For that pairing, see Apache Airflow vs Airbyte and Apache Airflow vs Fivetran.
Side by side
| Aspect | Apache Airflow | Dagster |
|---|---|---|
| Central abstraction | DAGs of tasks; assets as scheduling and lineage objects since Airflow 3 | Software-defined assets; ops and jobs for task-style work |
| Current version | 3.3.2 (September 2026) | 1.13.25 (October 2026) |
| Licence | Apache-2.0 | Apache-2.0 (open source); Dagster+ is a commercial service |
| Time-based scheduling | Cron, presets and timetables on DAGs | Schedules that target assets or jobs; AutomationCondition.on_cron on assets |
| Data-aware triggering | Asset-aware scheduling (schedule=[Asset(...)]) with AND/OR conditions; AssetWatchers for external events |
Declarative Automation (for example AutomationCondition.eager()), sensors and asset sensors |
| Lineage in the UI | Asset graph view and asset overlays on the DAG graph | Asset lineage graph at the centre of the UI; column lineage in the Dagster+ catalog |
| Managed options | Astronomer, Amazon MWAA and MWAA Serverless, Google Managed Service for Apache Airflow (formerly Cloud Composer) | Dagster+ Serverless or Hybrid (vendor-hosted control plane) |
| Self-hosting | Scheduler, Dag processor, API server, metadata database (PostgreSQL or MySQL), optional workers and triggerer | Webserver, daemon (schedules, sensors, run queue), code location servers, run storage (SQLite by default, PostgreSQL for production) |
| Main trade-off | Assets are an addition to a task-first model; lineage is only as complete as the outlets you declare | Asset-first thinking is a bigger shift for task-oriented teams; managed hosting means Dagster+ |
Key differences
Task-based DAGs versus software-defined assets
The same small pipeline (read some orders, compute a total, refresh daily at 06:00 UTC) shows the difference. In Airflow you describe steps: three tasks wired into a DAG. In Dagster you describe outputs: two assets, where order_total depends on raw_orders because it takes it as a function argument, and a schedule that materialises both. Both examples follow the official documentation and were syntax-checked with Python 3.14.
# Apache Airflow 3 (TaskFlow API, airflow.sdk)
import pendulum
from airflow.sdk import dag, task
@dag(
schedule="0 6 * * *",
start_date=pendulum.datetime(2026, 1, 1, tz="UTC"),
catchup=False,
tags=["orders"],
)
def daily_orders():
@task(retries=2)
def extract() -> list[dict]:
return [{"id": 1, "amount": 120.0}, {"id": 2, "amount": 80.0}]
@task()
def transform(rows: list[dict]) -> float:
return sum(r["amount"] for r in rows)
@task()
def load(total: float) -> None:
print(f"Total order value: {total:.2f}")
load(transform(extract()))
daily_orders()# Dagster 1.13 (software-defined assets)
import dagster as dg
@dg.asset
def raw_orders() -> list[dict]:
return [{"id": 1, "amount": 120.0}, {"id": 2, "amount": 80.0}]
@dg.asset
def order_total(raw_orders: list[dict]) -> float:
total = sum(r["amount"] for r in raw_orders)
print(f"Total order value: {total:.2f}")
return total
daily_refresh = dg.ScheduleDefinition(
name="daily_refresh",
cron_schedule="0 6 * * *",
target=[raw_orders, order_total],
)
defs = dg.Definitions(
assets=[raw_orders, order_total],
schedules=[daily_refresh],
)In Dagster, values returned by assets are stored and loaded by I/O managers, so order_total receives raw_orders without you writing the hand-off; when an asset writes to a database itself (for example with CREATE TABLE ... AS SELECT), you declare the dependency with deps=[...] instead, and nothing is passed. Each asset has a materialisation history, so the UI can show when a table was last refreshed and from which run. In Airflow, values pass between tasks through XComs, and what a task produced is visible to the scheduler only if you declare it as an outlet asset.
Airflow 3 assets: how close does Airflow get?
Airflow 3 made assets more central. A producer task declares outlets=[asset], and a consumer DAG uses schedule=[asset] to run when the asset is updated; multiple assets combine with & and |. The documentation also describes an @asset decorator that creates an asset, a DAG and a task in one step, and AssetWatchers that turn external events into asset updates.
# Apache Airflow 3: asset-aware scheduling
import pendulum
from airflow.sdk import Asset, dag, task
orders_file = Asset("s3://example-bucket/orders.parquet")
@dag(schedule="@daily", start_date=pendulum.datetime(2026, 1, 1, tz="UTC"), catchup=False)
def produce_orders():
@task(outlets=[orders_file])
def write_orders() -> None:
... # write the file
write_orders()
@dag(schedule=[orders_file], start_date=pendulum.datetime(2026, 1, 1, tz="UTC"), catchup=False)
def report_orders():
@task()
def build_report() -> None:
... # runs after orders_file is updated
build_report()
produce_orders()
report_orders()The difference that remains is emphasis. Airflow's documentation says it "makes no assumptions about the content or location of the data represented by the URI, and treats the URI like a string": an Airflow asset is a scheduling signal and lineage marker attached to tasks. In Dagster the asset is the unit you define, materialise, partition, check and automate, and the task is the means of producing it. Teams that already have many task-based DAGs can adopt Airflow assets gradually; teams starting from a data model may find Dagster's approach more direct.
Scheduling and automation
Airflow offers cron expressions, presets and custom timetables, asset-aware scheduling and event-driven scheduling through the REST API or AssetWatchers. In Airflow 3, catchup defaults to False, backfills are managed by the scheduler and can be launched from the UI, and SLAs were deprecated and replaced by Deadline Alerts.
Dagster documents several mechanisms: schedules (cron, run in UTC unless you set execution_timezone), sensors for external events, asset sensors, GraphQL triggers, and Declarative Automation, where each asset carries a condition such as dg.AutomationCondition.eager() (update when dependencies change) or dg.AutomationCondition.on_cron("@hourly"). The documentation notes that Declarative Automation needs the default automation condition sensor to be switched on in the UI.
UI and observability
Airflow 3's rewritten React UI centres on the Dags list and the Grid view, which its documentation calls "the primary interface for inspecting Dag runs and task states", plus a Graph view, task instance logs, an asset list and asset graph, and admin pages for connections, variables and pools. DAG versioning shows which code version a past run used.
Dagster's UI (served by dagster-webserver, started locally with dg dev) centres on assets: the asset lineage graph, materialisation history, and buttons to materialise selected assets, alongside runs, schedules and sensors. Dagster+ adds Insights for platform trends and cost, alerts to Slack, PagerDuty and email, an asset catalog with advanced search and column lineage, role-based access control and audit logs, and branch deployments for testing changes.
Deployment: self-hosted, managed Airflow or Dagster+
Self-hosted Airflow needs a scheduler, a Dag processor, an API server that also serves the UI, and a metadata database, usually PostgreSQL or MySQL, with workers and a triggerer as optional components. Managed Airflow is available from Astronomer (Astro Runtime 3.3-8 is based on Airflow 3.3.2), Amazon MWAA (newest listed version 3.3.1, plus MWAA Serverless, announced November 2025) and Google's Managed Service for Apache Airflow, previously known as Cloud Composer, which lists Airflow 3.3.1 builds.
Self-hosted Dagster runs a webserver, a single daemon for schedules, sensors and run queuing, and one or more code location servers, with SQLite run storage by default and PostgreSQL for production. Its documentation covers local deployment, running as a service, Kubernetes, Docker Compose, AWS and Google Cloud. Dagster+ comes in two forms: Serverless, where "your Dagster code executes in our environment", and Hybrid, where Dagster+ runs the control plane and you run the execution layer in your own infrastructure.
Pricing and licensing
Apache Airflow is free and open source under the Apache-2.0 licence. Managed services charge by usage. As one dated example, the Amazon MWAA pricing page listed USD 0.49 per hour for a small environment in US East (N. Virginia) in October 2026, with additional workers, schedulers, web servers and metadata storage billed separately. Astronomer bills deployments by the hour plus worker compute while tasks run; Google's Managed Service for Apache Airflow has its own usage-based pricing. Use each provider's calculator for an estimate.
Dagster open source is free under the Apache-2.0 licence. Dagster+ is billed by plan plus credits, where the pricing page defines a credit as "the sum of asset materializations and ops executed". As listed on dagster.io/pricing in October 2026: Solo is USD 10 per month for 1 user and 1 deployment, with credits at USD 0.040 each; Starter is USD 100 per month for up to 3 users with credits at USD 0.035; Pro is priced on request. Dagster+ Serverless compute is billed per minute on top. Solo and Starter have a 30-day free trial.
We describe pricing models only and do not estimate bills. Note that the two models scale with different things: MWAA and Astronomer with environment and worker hours, Dagster+ with the number of materialisations and op executions.
Pricing checked on the vendors' official pages on 7 October 2026. Prices change; confirm before buying.
Where each one leads
Apache Airflow strengths
- Task-first model that fits any sequence of steps, not only data assets
- Asset-aware and event-driven scheduling since Airflow 3, adoptable gradually in existing DAGs
- The widest choice of managed services: Astronomer, Amazon MWAA (including Serverless) and Google's Managed Service for Apache Airflow
- Large ecosystem of provider packages and operators
- DAG versioning and scheduler-managed backfills in Airflow 3
Dagster strengths
- Software-defined assets make lineage and materialisation history the centre of the tool
- Declarative Automation sets update rules per asset (eager, on cron) instead of per pipeline
- Function arguments express dependencies, with I/O managers handling storage
- Local development UI with dg dev and asset materialisation from the browser
- Dagster+ Hybrid keeps execution in your own infrastructure while the vendor runs the control plane
Limitations
Apache Airflow limitations
- Assets are scheduling signals attached to tasks; Airflow treats the asset URI as a string and does not track its contents
- More components to run when self-hosting: scheduler, Dag processor, API server and metadata database
- Airflow 3 removed or replaced several Airflow 2 features (SubDAGs, SLAs, execution_date), so upgrades need work; Airflow 2.x is end of life
- Managed services trail the open source release by weeks or months
Dagster limitations
- Asset-first design is a bigger change for teams used to task-based pipelines
- Managed hosting means Dagster+; there is no Dagster service from the major cloud providers
- Several team features (Insights, column lineage in the catalog, RBAC, branch deployments) are Dagster+ features
- Dagster+ cost grows with the number of asset materialisations and op executions
- Declarative Automation needs its sensor enabled before conditions take effect
When to choose each
Choose Apache Airflow if
- Your pipelines are sequences of operational steps (calling APIs, moving files, running jobs) rather than a set of tables
- You want a managed service from AWS, Google Cloud or Astronomer
- You already run Airflow and want data-aware scheduling without a migration
- You depend on Airflow provider packages for your systems
Choose Dagster if
- You model your platform as tables, files and models and want lineage and freshness per asset
- You use dbt and want each dbt model shown as an asset in one lineage graph, which Dagster's dbt integration documents
- You want automation rules per asset, such as refresh when upstream data changes
- You want the vendor to run the control plane while code runs in your own cloud (Dagster+ Hybrid)
When neither is right
- You want to orchestrate existing Python scripts with native control flow and event-driven automations: look at Prefect; see Apache Airflow vs Prefect and Prefect vs Dagster.
- Your main need is copying data from SaaS applications and databases into a warehouse: a connector-based ingestion tool may be enough; see Apache Airflow vs Airbyte, Apache Airflow vs Fivetran and the best ETL tools guide.
- You have a handful of SQL jobs in one database: the database's own scheduler (SQL Server Agent, or pg_cron for PostgreSQL) may be enough. ETL vs data pipeline explains the terms.
Final recommendation
The choice comes down to what you want the orchestrator to centre on. Apache Airflow centres on tasks and runs; Airflow 3 added first-class assets, an @asset decorator and event-driven scheduling, and it has the broadest managed hosting. Dagster centres on the assets themselves, with lineage, materialisation history and per-asset automation built in, and Dagster+ as its managed platform. Teams with a large Airflow estate can get much of the data-aware behaviour by adopting Airflow assets; teams designing a new analytics platform around tables and models should evaluate Dagster seriously.
Frequently asked questions
Did Airflow rename datasets to assets?
Yes. The Airflow documentation says the asset concept "was previously called 'Dataset'" and changed in version 3.0. The upgrade guide maps airflow.datasets.Dataset to airflow.sdk.Asset, and DatasetAlias, DatasetAll and DatasetAny to AssetAlias, AssetAll and AssetAny.
What is a software-defined asset in Dagster?
A Python function decorated with @dg.asset that produces a persistent object such as a table, file or model. Dependencies between assets, declared with function arguments or deps, form a lineage graph, and Dagster records each materialisation.
Can Dagster run Airflow-style task pipelines?
Yes. Besides assets, Dagster has ops and jobs for task-style work, and its schedules and sensors can target jobs as well as assets. Dagster+ credits count both asset materialisations and op executions.
Is Dagster free?
Dagster open source is free under the Apache-2.0 licence and can be self-hosted. Dagster+ is paid, with Solo and Starter plans (30-day free trial) and a Pro plan priced on request, plus usage-based credits.
Which managed services support Airflow 3?
As checked in October 2026: Astronomer (Astro Runtime 3.3-8, based on Airflow 3.3.2), Amazon MWAA (Airflow 3.3.1 and earlier 3.x versions) and Google's Managed Service for Apache Airflow, previously known as Cloud Composer (Airflow 3.3.1 builds). Amazon also offers MWAA Serverless.
Sources
- Apache Airflow release notes
- Apache Airflow: Upgrading to Airflow 3
- Apache Airflow: Assets
- Apache Airflow: Asset-aware scheduling
- Apache Airflow: Architecture overview
- Apache Airflow: UI overview
- Apache Airflow: Supported versions
- Dagster documentation: Quickstart
- Dagster documentation: Asset dependencies
- Dagster documentation: Automation
- Dagster documentation: Declarative Automation
- Dagster documentation: dbt integration
- Dagster documentation: OSS deployment architecture
- Dagster+ documentation
- Dagster+ pricing
- dagster on PyPI
- Amazon MWAA: Supported Airflow versions
- Amazon MWAA pricing
- Astronomer pricing
- Google Cloud: Managed Service for Apache Airflow versions
Checked October 2026.
How we research comparisons: our editorial method.