Week 7 · Run it in production › Day 45
Day 45. Choosing tools with a written rationale
By the end of today you can
- Compare orchestrators (Dagster, Airflow, Prefect, Mage, Kestra, Data Factory) on criteria that matter
- Compare ingestion tools (dlt, Airbyte, Meltano, managed connectors) and transformation tools (dbt, SQLMesh)
- Port one pipeline to a second orchestrator and report what changed
- Write a weighted decision matrix and an ADR
1. Why this matters
Job ads list different tools: Airflow here, ADF there, Prefect somewhere else. You can't master all of them in 7 weeks, but you can understand the shared concepts (Weeks 1–6) and how each tool expresses them. That's what lets a senior person switch tools in a week.
2. Orchestrators
| Dagster | Airflow | Prefect | Mage | Kestra | Azure Data Factory / Fabric | |
|---|---|---|---|---|---|---|
| Model | Assets (data-first) | Tasks/DAGs (assets added in v3) | Python flows/tasks | Blocks in a notebook-like UI | YAML flows, event-driven | Low-code pipelines |
| Local dev & tests | Excellent | Improved; heavier | Very easy | Easy | Easy (Docker) | Portal-based |
| Partitions/backfills | First-class | Good (data intervals) | Manual patterns | Basic | Good | Tumbling windows |
| Lineage | Built-in, column-level with dbt | Via OpenLineage | Limited | Basic | Basic | Via Purview |
| Ecosystem | Growing, strong dbt/dlt | Largest (providers) | Good | Smaller | Growing | Azure-native connectors |
| Hosting | OSS or Dagster+ | OSS, MWAA, Astronomer, Cloud Composer | OSS server or Prefect Cloud | OSS or Pro | OSS or Enterprise | Pay per activity |
Airflow skills are still the most requested in ads; Dagster is increasingly common in modern stacks; ADF is everywhere in Microsoft enterprises.
The same pipeline in Airflow (TaskFlow API)
from airflow.sdk import dag, task # Airflow 3; in Airflow 2: from airflow.decorators import dag, task
import pendulum
@dag(schedule="15 6 * * *", start_date=pendulum.datetime(2026, 9, 1, tz="America/Toronto"), catchup=True)
def hotel_daily():
@task(retries=3)
def land(ds=None): # ds = logical date as YYYY-MM-DD, the "business date" for this run
return pms.land_day(ds)
@task
def stage(path: str):
return pms.stage(path)
stage(land())
hotel_daily()
And in Prefect
from prefect import flow, task
@task(retries=3, retry_delay_seconds=30)
def land(bdate: str) -> str: return pms.land_day(bdate)
@flow
def hotel_daily(bdate: str): pms.stage(land(bdate))
Notice your pms core module didn't change. That's the payoff of the Day 15 rule.
3. Ingestion tools
- dlt: Python library, code-first, runs inside any orchestrator, cheap. Great for APIs and files.
- Airbyte: hundreds of connectors with a UI; self-host (needs a bit of infrastructure) or cloud.
- Meltano: Singer taps/targets with CLI and config, OSS.
- Fivetran / Azure Data Factory copy / Fabric: managed connectors, priced per volume/activity; the fastest start, the highest bill at scale.
4. Transformation
dbt (Core is open source; dbt Cloud adds hosted IDE/scheduling) is the default. SQLMesh is the strongest alternative, with virtual environments and plan/apply. Stored procedures remain common in SQL Server shops.
Maths and principle
Principle: a weighted decision matrix makes trade-offs explicit and arguable.
Equation: score\(_j = \sum_i w_i s_{ij}\) with \(\sum w_i = 1\), scores \(s_{ij} \in [1, 5]\). Run a sensitivity check: does the winner change if any single weight moves by ±0.1? If yes, the decision is close and depends on that criterion; say so.
Analogy: a weighted least-squares fit: weights encode how much you trust each measurement. Where it breaks: double-counting correlated criteria ("easy to learn" and "fast onboarding") inflates them. Merge them.
Try it: weights cost 0.4, skills fit 0.4, features 0.2. Tool A scores 3, 5, 4; Tool B scores 5, 2, 5. Winner? (A: 1.2 + 2.0 + 0.8 = 4.0; B: 2.0 + 0.8 + 1.0 = 3.8 → A, narrowly.)
The 5-year lens
Interviewers ask "why Dagster and not Airflow?" to see if you can argue both sides. A good answer: "Dagster's asset model, partitions and local testing suited a small team building a new platform. In a company with 300 existing Airflow DAGs and an Airflow-skilled team, I'd stay on Airflow 3, adopt its asset features and OpenLineage, and keep business logic in plain Python and dbt so the orchestrator stays swappable."
Lab
- Port the hotel pipeline (land → stage → OTB) to Airflow (Astro CLI or the official Docker Compose) or Prefect (
pip install prefect; prefect server start). Keep the core module unchanged. - Run a backfill in that tool. Note how partitions/intervals work there compared with Dagster.
- Re-implement the ads ingest with dlt and, if your machine allows, try Airbyte OSS with its Postgres destination.
- Build a weighted decision matrix for three company profiles (40-store Microsoft retail chain; 300-restaurant Google Workspace QSR; 5-hotel group with no IT team). Do the sensitivity check.
- Write ADR-002 (orchestrator) and ADR-003 (ingestion) for the capstone.
Ship
docs+feat: Airflow/Prefect port, dlt/Airbyte trial, decision matrices, ADR-002/003.
Check yourself
1. You ported a pipeline from Dagster to Prefect and only changed the orchestration file. What made that possible?
Thin orchestration layers keep tools swappable.
2. A company has 300 Airflow DAGs and an Airflow-skilled team. Best recommendation?
Migration cost and team skills dominate.
3. In a sensitivity check, the winner flips when one weight changes by 0.1. What do you report?
Make the hinge visible.