Dagster is an open-source Python data orchestration platform that models your data pipelines as a graph of assets (tables, files, and ML models) rather than a sequence of tasks. Built by Dagster Labs and licensed Apache 2.0, it has 15,740 GitHub stars, 15 million PyPI downloads in 2024, and production deployments at DoorDash, Vanta, and Magenta Telekom. Its core idea: define what data to produce, and Dagster figures out the execution order automatically.
This guide covers Dagster's asset model, the 2026 quickstart toolchain, the dbt integration, a neutral comparison with Apache Airflow, and an honest look at pricing. It includes the cloud tier controversy you'll encounter in r/dataengineering before committing.
Key Takeaways
- Dagster uses Software-Defined Assets (SDAs): Python functions that declare what data to produce, not which tasks to run. Execution order is inferred from function arguments.
- The 2026 recommended install path is
uvx create-dagster@latest project my-project, which scaffolds a full project in seconds. dagster-dbt is the tightest dbt integration in the orchestrator ecosystem, with full lineage from raw sources through dbt models to downstream consumers.- Dagster OSS is fully production-capable. The paid Dagster+ cloud adds managed infra, RBAC, and SSO, not core orchestration features.
- Dagster Cloud pricing has been a community flashpoint. Most practitioners running at scale self-host on AWS ECS Fargate for near-zero Dagster cost.
What Is Dagster?
Dagster is an asset-centric data orchestration platform where the primary building block is a data object (a table, a file, or a trained model) rather than a job or task. You define assets as Python functions decorated with @dg.asset.
Dagster infers the execution DAG automatically from the function arguments. No explicit >> wiring, no task dependency graph to maintain by hand.
Nick Schrock, GraphQL co-creator and ex-Facebook engineer, started the project in 2018 after a sabbatical spent rejecting drag-and-drop ETL tooling. Pete Hunt (ex-Facebook, early Elementl investor) joined as CEO. The company raised a $33M Series B led by Georgian in May 2023, bringing total funding to $48.8M.
Why asset-centric orchestration matters in 2026
Most orchestrators (Airflow included) model pipelines as sequences of tasks. Tasks define how to compute something; they say nothing about what was produced, whether it's still fresh, or what depends on it downstream. Those questions require separate data catalog tooling, documentation, and tribal knowledge.
Dagster's asset graph answers those questions structurally. Every asset carries metadata: its owner, its freshness policy, its upstream dependencies, its last materialization time. When stakeholders ask "Is this table ready for the board report?" the asset graph answers without a Slack thread.
Schrock framed the design philosophy when unveiling Software-Defined Assets in 2022: "Software engineering has grown increasingly declarative. Front-end development shifted from jQuery to React, describing what UI you want, not how to render it." Data pipelines stayed imperative: scripts, cron jobs, and task graphs that describe execution rather than the data itself. SDAs bring the same declarative shift to data.
That framing is absent from every third-party Dagster guide currently ranking in SERP. It is the reason experienced practitioners choose Dagster over tools with larger ecosystems.
How Dagster Works: The Software-Defined Asset Model
The @dg.asset decorator
The @dg.asset decorator is the primary primitive. Each decorated function produces one asset (by default, named after the function) and declares its upstream dependencies through its argument names.
import dagster as dg
import pandas as pd
@dg.asset
def raw_events():
"""Extract: pull from source API."""
return requests.get("https://api.source.com/events").json()
@dg.asset
def cleaned_events(raw_events):
"""Transform: filter and normalize."""
return [e for e in raw_events if e["valid"]]
@dg.asset
def events_table(cleaned_events):
"""Load: write to warehouse."""
df = pd.DataFrame(cleaned_events)
df.to_sql("events", connection, if_exists="replace")
Dagster reads the argument names, builds the dependency graph, and orchestrates execution. Change the argument name and you change the dependency. No graph class to instantiate, no >> to chain.
Name assets as nouns (what they produce), not verbs (what they do). logins instead of compute_logins. The naming convention is load-bearing: downstream assets reference upstream assets by name through their argument list.
Resources
Resources handle external services: Snowflake connections, S3 buckets, API clients. You define a resource once as a ConfigurableResource subclass, inject it into any asset that needs it, and swap implementations by environment.
class SnowflakeResource(dg.ConfigurableResource):
account: str
user: str
password: str
database: str
schema: str
warehouse: str
In development, you inject a lightweight in-memory mock. In production, you inject the real Snowflake credentials.
Dagster's resources guide covers environment-specific configuration in depth. This pattern makes Python automation pipelines testable without standing up real databases.
Schedules and sensors
Schedules trigger asset materializations on a cron cadence. Sensors trigger materializations when external conditions are met: a new file lands in S3, an upstream asset updates, or an API event fires.
@dg.sensor(job=ingest_job)
def new_file_sensor(context):
new_files = check_s3_for_new_files()
if new_files:
return dg.RunRequest(run_key=new_files[0])
Sensors map naturally to event-driven architectures. As BugBytes notes in "Dagster: Data Orchestration and Pipelines with Python": "This allows you to perform things in an event-driven manner and that flexibility is why Dagster is so good."
The dagster-daemon background process manages schedules and sensors. It runs alongside the webserver and must be running for automated triggering to work.
Partitions and backfills
Partitions slice assets by date or arbitrary key. DailyPartitionsDefinition(start_date="2023-01-01") creates one partition per calendar day. Materializing a single partition processes only that slice of data.
Backfills run historical partitions retroactively, critical for fixing data quality issues, onboarding new transformations, or reprocessing after schema changes. Dagster tracks which partitions succeeded, which failed, and which are missing, giving you a complete picture of your data coverage across the Python data analysis pipeline.
A common first-time gotcha: you must configure the partition key on the asset before materializing. Teams that miss this step hit confusion when backfills don't pick up historical data correctly.
Asset checks
Asset checks are inline data quality tests that run after an asset materializes. They're first-class Dagster objects: visible in the UI, linked to asset lineage, and blockable on failure. Built-in check types cover row count thresholds, null column validation, freshness windows, and schema drift detection.
Unlike external testing frameworks, asset checks run in the same execution context as the asset, with access to the same metadata. A failed check appears in the asset graph alongside the failed materialization, making root cause analysis faster.
I/O managers
I/O managers decouple storage from computation. Define how to read and write your asset type once; individual assets stay storage-agnostic. Tim (Timnology) summarizes the payoff in "Dagster 101":
"The beauty is that assets become storage agnostic. Switching from DuckDB to Snowflake. Change one line. No refactoring."
For teams exploring pandas alternatives like Polars or DuckDB, I/O managers mean you can swap the storage backend later without rewriting asset logic.
Components
Components are YAML-declarative scaffolding for common integrations. The DbtProjectComponent scaffolds an entire dbt project as Dagster assets without writing Python:
type: dagster_dbt.DbtProjectComponent
attributes:
project: '{{ project_root }}/dbt'
The Components system is part of Dagster's 2026 evolution toward "configuration as code" for common patterns.
Getting Started with Dagster in 2026
Prerequisites
- Python 3.10 or higher (3.13 recommended)
uv package manager (optional but strongly recommended)
Scaffold a project
uvx create-dagster@latest project my-project
cd my-project
source .venv/bin/activate
dagster dev
dagster dev launches the full Dagster UI at http://localhost:3000. The scaffolded project includes a working assets file, a definitions module, and a configured pyproject.toml. No Dockerfile, no Airflow Executor configuration, no LocalExecutor flag.
Add to an existing project
uv add dagster dagster-webserver dagster-dg-cli
# or with pip:
pip install dagster dagster-webserver dagster-dg-cli
Scaffold assets
dg scaffold defs dagster.asset assets.py
Project structure
my-project/
├── pyproject.toml
├── src/
│ └── my_project/
│ ├── __init__.py
│ ├── definitions.py
│ └── defs/
│ ├── __init__.py
│ └── assets.py
├── tests/
└── uv.lock
The definitions.py file is the entry point Dagster loads. It registers all assets, resources, schedules, and sensors.
The defs/ directory holds the actual asset code, organized however you like. This contrasts with Airflow's dags/ flat directory where every file is scanned for DAG objects.
No existing independent tutorial in the top SERP results for "dagster tutorial" or "dagster guide" uses the uvx create-dagster path. Every third-party guide still shows the bare pip install dagster. The 2026 CLI path appears only in Dagster's official quickstart.
dbt + Dagster: The Modern Data Stack Backbone
dagster-dbt is the tightest orchestrator-dbt integration in the ecosystem. dbt models appear as Dagster assets with full lineage from raw sources through transformations to downstream consumers, with no manual wiring.
from dagster_dbt import dbt_assets, DbtProject
my_dbt_project = DbtProject(project_dir="dbt/")
@dbt_assets(manifest=my_dbt_project.manifest_path)
def my_dbt_models(context, dbt):
yield from dbt.cli(["build"], context=context).stream()
Or with the declarative 2026 approach:
type: dagster_dbt.DbtProjectComponent
attributes:
project: '{{ project_root }}/dbt'
What the integration gives you
- Lineage: raw table to dbt model to downstream BI asset, tracked in the Dagster UI without additional configuration.
- Partitions: dbt incremental models map to Dagster partitions. Backfill a date range in Dagster and dbt processes only those partitions.
- Asset checks:
dbt test results become Dagster asset check results, surfaced in the same UI alongside materialization history. - Scheduling: freshness policies on dbt models trigger materializations when data goes stale.
smava, a German FinTech, automated the generation of 1,000+ dbt models with Dagster, cutting developer onboarding from weeks to 15 minutes with zero downtime migration.
On r/dataengineering, the dbt + Dagster combination consistently receives the strongest endorsements for dbt-heavy stacks.
u/L-i-a-h in r/dataengineering (June 2026) notes: "Dagster has a really nice dbt integration and help you visualize and inspect the whole DAG. But you basically have to self-host Dagster."
The lineage visualization auto-generates from the dbt project manifest without manual wiring, which is the most frequently cited reason practitioners adopt Dagster for dbt-heavy stacks.
Dagster vs Apache Airflow (2026)
dagster vs airflow receives 390 monthly US searches and represents the most common decision gate for data teams evaluating both tools.
Where Airflow still wins
Airflow has a 320M download lead and 10+ years of community patterns, plugins, and operators. If you're orchestrating primarily external compute (Spark jobs on EMR, Databricks workflows), Airflow's operator library is broader.
Airflow 3.2 (April 2026) added asset partitioning and multi-team deployments, directly narrowing Dagster's differentiation. Airflow 3.1.0 (September 2025) had already added Human-in-the-Loop operators. The "Dagster wins on assets" framing was cleaner before April 2026.
Where Dagster wins
Dagster answers questions Airflow cannot: Is this asset fresh? What produced this output? What downstream assets are affected?
The asset graph is a built-in data catalog, not an add-on. Local development is fast. Testing is built into the resource model.
u/Saetia_V_Neck in r/dataengineering (June 2026) describes the tradeoff: "I've used and managed both Dagster and Airflow at scale. I strongly prefer Dagster." The one exception Saetia names: pipelines built entirely around external Spark compute on EMR, where Airflow's broader operator library outweighs Dagster's development experience.
The practitioner heuristic: greenfield setups and dbt-heavy stacks favor Dagster. Existing Airflow deployments at scale, or pipelines built mostly around external Spark compute, favor staying on Airflow.
For teams already on Airflow, dagster-airlift enables coexistence: Dagster manages new pipelines while Airflow DAGs keep running.
Deploying Dagster
OSS deployment options
OSS architecture components:
dagster-webserver: UI and GraphQL APIdagster-daemon: Background process managing schedules, sensors, and run queue- Code location server: Isolated per team or project
- Storage: PostgreSQL (production) or SQLite (development)
Self-hosted Dagster on AWS ECS Fargate is the community's most-validated production path. u/ardentcase in r/dataengineering (Feb 2026) reports:
"I'm a team of one, running OSS on ECS/Fargate. 20 pipelines, ~100 GB of data per day. Only paying for Fargate (serverless) and S3, so it's as cheap as it gets. Almost no infra maintenance, would never consider a paid version."
The Kubernetes Helm chart gets consistent praise for teams with existing cluster infrastructure.
Pricing: OSS vs Dagster+ Cloud
Open-source (free)
The Apache 2.0 core covers full orchestration, scheduling, observability, the asset graph, dbt integration, partitions, sensors, and asset checks. HIVED, a UK logistics company, has run Dagster OSS in production for three years at 99.9% pipeline reliability.
Dagster+ (managed cloud)
Credits are consumed per asset materialization or op execution. Serverless compute is charged separately per minute.
The exact cost for a real workload (say, 20 pipelines processing 100 GB/day) depends on materialization frequency and compute type. Dagster's pricing page does not provide a worked example.
Three separate high-upvote r/dataengineering threads emerged in 2025–2026 about Dagster's managed tier pricing changes, with practitioners reporting quotes nearly double their existing Snowflake spend and short migration windows. The frustration targets the managed offering specifically, not the open-source framework.
u/Beautiful-Dot2454 in r/dataengineering (May 2026) put it plainly: "Been self hosting Dagster on AWS ECS. Works like a dream. Will never go back to Airflow or any airflow-managed service again."
The community consensus: Dagster OSS is production-capable. The paid tier adds managed infrastructure, RBAC, SSO, and column-level lineage, not core orchestration features. SSO (SAML/OIDC) is the one feature that meaningfully gates enterprise adoption, as it requires the Pro tier.
Common Dagster Mistakes to Avoid
Treating Dagster as Airflow with better Python
This is the most expensive paradigm error. Airflow DAGs describe execution sequences; Dagster assets describe data objects.
Teams that translate Airflow DAGs one-to-one miss Dagster's actual value: the asset graph's ability to answer freshness and lineage questions structurally. Redesign around what data you produce, not what steps you run.
Naming assets as verbs
compute_revenue_report describes a task. revenue_report describes an asset. The naming distinction matters: Dagster downstream assets reference upstream assets by function name through their argument list. A verb-named asset signals that you're still thinking in task sequences.
Skipping I/O managers for early prototypes
Skipping I/O managers is fast at the start and expensive later. Once you've written 20 assets that each contain explicit pd.to_sql() calls, migrating to a different storage backend requires touching every asset. Define a minimal I/O manager in week one; swap the implementation when you need to.
Running dagster-daemon without process supervision
dagster-daemon manages schedules and sensors. If it stops, scheduled runs stop silently.
In production, run it under systemd, Kubernetes, or Docker with a restart policy. A stopped daemon with no alerting is a common source of "the pipeline didn't run last night" incidents.
Materializing partitioned assets without setting the partition key configuration
Partitioned assets require partition key configuration before materialization. Teams that skip this step discover the gap only when backfills fail to pick up historical data, often weeks into production. Configure the partition definition and verify with a dry-run before deploying partitioned assets.
Dagster in Practice: Vanta's 14x Data Freshness Improvement
Vanta, a security compliance platform, rebuilt its data infrastructure on Dagster to solve a reliability problem: compliance auditors needed fresh, trustworthy data, and the existing pipeline couldn't reliably deliver it.
After migrating to Dagster's asset model, Vanta achieved 14x fresher data while reducing pipeline maintenance overhead. The asset graph gave the data team visibility into which assets were stale, which had failed, and which downstream reports were affected. The asset graph eliminated the manual investigation those questions previously required.
The compliance use case fits Dagster naturally. Regulators ask: "Is this data current and verifiable?" The asset graph is built to answer that question structurally, not through documentation or human memory.