All capabilities · Data engineering & analytics

Build scheduled data pipelines

Airflow/dbt/Spark basics: extract, transform, load into a warehouse with tests and lineage.

~25 focused hoursintermediate
Explore 3 tools for this project
Market relevance

Which roles ask for this — and how often

Share of job postings in India, per role, that name this capability.

What employers mean

You should be able to…

  1. Write an Airflow DAG with proper task dependencies, retries, and scheduling
  2. Build dbt models with tests (not null, unique, referential integrity) and documented lineage
  3. Design idempotent ETL so re-running a job doesn't duplicate data
  4. Handle incremental loads instead of always doing a full table refresh
  5. Add data-quality checks that fail the pipeline loudly instead of silently loading bad data
  6. Debug a failed pipeline run from logs and backfill the missing partition/date
  7. Document data lineage so downstream users know where a column's value actually came from

Needs first: Query and model data with SQL, Write production-quality Python for AI work

Learn — free, link-checked

The few resources that matter

Tools for practice

Choose a tool for the job

Start with one tool for each part of your project. You don’t need to learn them all.

Go to the practice brief

3 tools to explore

Apache Airflow

Data · Automate

Schedule dependent data tasks and practise retries, backfills and failure recovery.

Practice

Daily incremental warehouse pipeline with Airflow, dbt and data tests

Use the NYC TLC trip-record parquet files as a stand-in daily feed: split one month into day-sized partitions and land them one at a time so the pipeline sees a real arriving feed. Build an Airflow DAG that loads each day incrementally into local Postgres, transforms it with dbt staging and mart models, and runs dbt tests for nulls, uniqueness and referential integrity. Then break it on purpose — feed a day with corrupted rows and confirm the run fails loudly instead of quietly writing bad marts. Finish by backfilling a day you deliberately skipped.

Start from

NYC TLC trip-record parquet files — public monthly downloads you split into day partitions to simulate a daily feed

Milestones
  1. Stand up Postgres and Airflow, land one day's partition end to end · ~4h
  2. Build the DAG with real task dependencies, retries and a date parameter that makes re-runs idempotent · ~6h
  3. Write the dbt staging and mart models and generate the lineage docs · ~5h
  4. Add the four data tests and prove the pipeline fails on a deliberately corrupted day · ~3.5h
  5. Skip a day, backfill it, and document the backfill procedure · ~2.5h
Done when
  • DAG has explicit task dependencies and retry configuration, not one monolithic Python task
  • Loads are incremental — re-running for the same date does not duplicate rows
  • At least 4 dbt tests are defined and the pipeline fails visibly when a test fails on bad input data
  • README explains how to trigger a backfill for a missed date and includes a lineage diagram (even hand-drawn)
Prove it

Evidence a recruiter can check

  • Airflow run history showing the same date executed twice with identical row counts — the idempotency claim, evidenced
  • The deliberately-failed run: the corrupted input, the dbt test that caught it, and the marts that were left untouched
  • dbt docs lineage graph from staging through to marts, generated not drawn
  • The backfill: a gap in the run history, the command that filled it, and the row counts before and after
Signal it

Built a daily Airflow + dbt pipeline with incremental idempotent loads and four data tests — demonstrated it catching a corrupted day's feed before it reached the marts, and backfilling a missed date cleanly.

Interview

Questions you'll get asked

  1. Walk me through the DAG you'd write to load daily sales data from an API into a warehouse.
  2. How do you make an ETL job idempotent so re-running it twice doesn't double-count?
  3. What's the difference between a full refresh and an incremental load, and when do you use each?
  4. How would you add a test that fails the pipeline if 5% of rows suddenly have null customer_id?
  5. A DAG failed at 3am on one task — walk me through how you'd debug and backfill it.
  6. What's dbt for, and how is it different from writing raw SQL scripts in a cron job?
  7. How do you track data lineage so someone can trace a dashboard number back to its source table?