ETL & Data Pipelines
Topic 3 of 12 · In Business Intelligence · September 9, 2026
Learn how data moves from source systems into the warehouse: the Extract-Transform-Load process, ETL vs ELT, tools, scheduling, error handling and data quality gates.
Overview
ETL stands for Extract, Transform, Load — the process of pulling data from source systems, reshaping it into the right structure, and loading it into a target (usually a data warehouse). Without reliable ETL pipelines, a warehouse is just an empty shell, and dashboards show stale or wrong data.
This topic teaches you how ETL pipelines work in practice: the difference between ETL and ELT, the major tools used in the industry, how to schedule and monitor pipelines, handle errors gracefully, enforce data quality gates, and choose between incremental and full loads. These skills are essential whether you are a BI engineer building pipelines or a BI analyst who needs to understand where the data in your dashboards comes from.
Before You Start
- Have the fact_sales and dim_product tables you designed in the data warehousing topic open, since they are the load targets for every pipeline in this topic
- Install and verify dbt Core locally with a SQLite or DuckDB adapter, or open the ETL tool of your choice (SSIS, Talend, Azure Data Factory)
- Download the three mock CSVs from the mini project (users.csv, usage.csv, payments.csv) and inspect the column types and null counts
- Be able to write a WHERE clause and a simple aggregate in SQL without reference, because ELT transformations and quality tests are expressed in SQL
- Decide and write down a real refresh schedule (for example nightly at 02:00) to encode as the pipeline schedule
Learning Objectives
- Explain the Extract-Transform-Load process step by step
- Distinguish between ETL and ELT and when to use each
- Compare major ETL tools: SSIS, Talend, Azure Data Factory, dbt and Informatica
- Design a pipeline schedule with dependencies and retries
- Implement error handling and logging in a pipeline
- Apply data quality gates to block bad data from reaching the warehouse
- Choose between incremental and full data loads based on data volume and freshness needs
- Understand change data capture (CDC) and its role in incremental loads
Prerequisites
Continue from Data Warehousing Concepts to understand the warehouse target. SQL basics from SQL for Business Intelligence will help but are not required for the conceptual parts of this topic.
The ETL Process
ETL is a three-stage pipeline:
- Extract — connect to source systems (databases, APIs, files, streams) and pull data. Extraction must handle different formats (SQL tables, JSON APIs, CSV exports), connectivity (JDBC, REST, SFTP) and timing (real-time vs batch).
- Transform — clean, standardize, enrich and restructure the data. Common transformations: type casting, null handling, deduplication, lookup enrichment, aggregation, business rule application, format standardization.
- Load — write the transformed data into the target warehouse or mart. Loading strategies include full replace, append, merge (upsert) and slowly changing dimension handling.
Each stage has its own challenges. A robust pipeline handles failures at any stage without corrupting the target — ideally through transactional loads (all-or-nothing) and staging tables (transform into a temporary area, then swap into production).
ETL vs ELT
The difference is where the transformation happens:
| Aspect | ETL | ELT |
|---|---|---|
| Transformation location | In the ETL tool (middleware) | In the target database / warehouse |
| Best for | Small-to-medium data, complex business rules | Large data volumes, cloud warehouses |
| Tools | SSIS, Talend, Informatica | dbt, Snowflake SQL, BigQuery scripting |
| Performance | Limited by middleware server | Leverages warehouse compute (scales) |
| Flexibility | Transformations in proprietary code | Transformations in pure SQL (version-controlled) |
Modern trend: cloud warehouses (Snowflake, BigQuery, Synapse) are powerful enough that ELT is now the dominant pattern — load raw data first, then transform it with SQL (often using dbt). ETL still dominates in on-premises environments and when sources require pre-processing before loading.
-- ELT pattern with dbt: transform after loading
-- models/staging/stg_orders.sql
SELECT
order_id,
customer_id,
CAST(order_date AS DATE) AS order_date,
UPPER(TRIM(status)) AS status,
amount
FROM {{ source('raw', 'orders') }}
WHERE order_date IS NOT NULLMajor ETL Tools
| Tool | Type | Strengths | Best For |
|---|---|---|---|
| SSIS | On-prem ETL | Deep SQL Server integration, visual designer, mature | Microsoft / on-prem environments |
| Talend Open Studio | Open-source ETL | Drag-and-drop, 1000+ connectors, community edition | Budget-conscious, multi-source integration |
| Azure Data Factory | Cloud orchestration | Scales in Azure, integrates with Synapse/Databricks | Cloud-native Azure shops |
| dbt | SQL transformation (ELT) | Version-controlled SQL, testing, documentation, community | Cloud ELT, analytics engineering |
| Informatica | Enterprise ETL | Enterprise governance, huge connector library | Large enterprises, complex compliance needs |
| Fivetran / Airbyte | Managed extraction | Pre-built connectors, minimal config | Loading SaaS data into warehouses |
For this path, you will learn dbt (for SQL-based ELT) and Azure Data Factory concepts (for orchestration). These represent the modern, cloud-native approach most employers expect.
Scheduling, Dependencies and Monitoring
Pipelines do not run once — they run on a schedule (hourly, daily, weekly) and depend on each other in a directed acyclic graph (DAG):
- Schedule — define when each pipeline runs. Daily at 2 AM is common for batch; real-time streaming for near-instant needs.
- Dependencies — the dimension pipeline must finish before the fact pipeline starts (facts reference dimension keys).
- Retries and alerting — if a pipeline fails, retry 2–3 times with backoff, then alert the team (email, Slack, PagerDuty).
- Idempotency — running a pipeline twice should produce the same result as running it once. Use merge/upsert, not blind append.
- Logging and lineage — record what ran, how long it took, how many rows moved, and any errors. Tools like dbt and Airflow provide this natively.
Error Handling and Data Quality Gates
Production pipelines fail. The question is not if but how gracefully. A robust pipeline implements:
- Pre-load validation — check source data before transforming: null counts, row count thresholds, schema validation, referential integrity. If validation fails, block the load and alert.
- Quality gates — automated checks between stages. Example: "if more than 5% of rows have null revenue, stop the pipeline."
- Error logging — capture failed rows, error messages and timestamps into an error table for investigation.
- Quarantine pattern — instead of failing the whole load, route bad rows to a quarantine table. Load the good rows; investigate and fix the bad ones separately.
- Post-load reconciliation — compare row counts and checksums between source and target after loading. If they do not match, alert.
-- dbt data quality test example (schema.yml)
version: 2
models:
- name: stg_orders
columns:
- name: order_id
tests:
- unique
- not_null
- name: revenue
tests:
- not_null
- dbt_utils.accepted_range:
min_value: 0
max_value: 1000000Incremental vs Full Loads
Full load replaces the entire target table with all source data every run. Simple, but slow and expensive on large tables.
Incremental load only processes new or changed rows since the last run. Faster, cheaper, but requires a way to identify changes (timestamps, CDC, or hash comparisons).
Hands-On Practice
You can practice ETL with dbt Core (free, runs locally with SQLite or DuckDB) or with any ETL tool you have access to.
- Download a public CSV dataset with 5,000+ rows (e.g. from Kaggle). Write a simple ETL pipeline that: extracts from CSV, transforms (rename columns, cast types, handle nulls, add a calculated column), and loads into a SQLite database.
- Convert your pipeline to dbt: set up a dbt project, define a staging model and a mart model, add tests.
- Implement a full load strategy first, then convert to incremental: add a
updated_attimestamp and filter for only new/changed rows. - Add three data quality checks: not-null on key columns, a value range check, and a uniqueness check.
- Simulate a failure: corrupt 5 rows in the source (nulls in required fields). Verify your quality gate catches them.
- Document your pipeline: what it does, what sources it reads, what it produces, and how to run it.
Deeper Worked Examples
Rows go missing after a nightly load
Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Common Mistakes
- Loading directly into production tables without staging — a partial load corrupts the warehouse
- Blind appending without idempotency — re-running creates duplicates
- Ignoring source data quality — garbage in, garbage out, no matter how good your transform is
- Building a monolithic pipeline — split into small, testable, independently schedulable steps
- No alerting — a failed pipeline that nobody knows about is worse than no pipeline
- Choosing full load for a billion-row fact table — incremental loads are not optional at scale
- Hardcoding credentials in pipeline scripts — use secrets managers and environment variables
Real-World Usage
In production BI, ETL pipelines are the unsung heroes. A retail company runs nightly ETL that pulls POS data from 500 stores, cleans it, loads it into a warehouse, and by 6 AM the dashboards are ready. A bank runs real-time CDC pipelines that feed fraud detection systems. When pipelines break — and they do — the BI engineer is the one who notices the alert, diagnoses the root cause (source API changed, disk full, bad data from a new store), and fixes it before the business sees wrong numbers. This topic gives you the mental model to build and troubleshoot those systems.
Mini Project
Business problem: A SaaS company tracks user signups, feature usage and subscription payments across three systems. They need a nightly pipeline that combines this data into a warehouse for their BI dashboards.
Dataset: create three mock CSVs: users.csv (1,000 rows: user_id, name, email, signup_date, plan), usage.csv (10,000 rows: user_id, feature_name, usage_date, session_duration), payments.csv (2,000 rows: user_id, payment_date, amount, status).
Objective: build a dbt project that stages, transforms and tests this data.
Task 1
Task 2
Task 3
Task 4
Task 5
Task 6
dbt run && dbt test. Verify all tests pass.Task 7
updated_at column and convert one model to incremental.| Deliverable | What It Proves |
|---|---|
| 3 staging models with cleaning | You can implement the Extract + Transform stages |
| 2 mart models (dim + fact) | You understand how staging feeds the warehouse |
| 5+ dbt tests passing | You can enforce data quality gates |
| Incremental model conversion | You understand incremental vs full loads |
| Pipeline documentation | You can communicate pipeline design to a team |
Key Takeaways
- ETL = Extract (pull from sources), Transform (clean, reshape), Load (write to warehouse)
- ELT loads raw data first, transforms in the warehouse — dominant pattern in cloud BI
- Key tools: SSIS (on-prem), Talend (open-source), ADF (cloud), dbt (SQL ELT), Fivetran/Airbyte (managed extraction)
- Pipelines need scheduling, dependency management, retries, alerting and idempotency
- Data quality gates: pre-load validation, quarantine pattern, post-load reconciliation
- Full load for small tables; incremental load (CDC or timestamp) for large fact tables
- Stage before production, test before loading, log after loading
Key Terms & Glossary
| Term | Meaning |
|---|---|
| ETL | Extract-Transform-Load: data is extracted from sources, transformed in middleware and then loaded into the warehouse target. |
| ELT | Extract-Load-Transform: raw data is loaded into the warehouse first and transformed with SQL, using the warehouse's compute rather than middleware. |
| DAG | A directed acyclic graph of pipeline steps showing which jobs must finish before others start, such as dimensions before facts. |
| Idempotency | A pipeline property where re-running a job produces the same result as running it once, achieved with merges and surrogate keys rather than blind appends. |
| Change data capture | A technique for identifying and extracting only the new or changed rows since the last run, the basis of incremental loads on large fact tables. |
| Quality gate | An automated check between pipeline stages that blocks, quarantines or alerts on bad data before it can reach the production warehouse. |
Learning Resources
dbt Documentation
The official dbt docs — the best resource for learning SQL-based ELT with models, tests and documentation.
Microsoft Learn — Azure Data Factory
Microsoft's guided learning path for building cloud data pipelines with ADF.
Coursera — Data Pipelines with Python
Learn to build ETL pipelines with Python, Airflow and cloud services.
Talend Open Studio Documentation
Free, open-source ETL tool documentation with tutorials and examples.
Andy Jones — dbt on YouTube
Practical dbt tutorials covering modeling, testing and production deployment.
Fivetran — The Modern Data Stack
A clear overview of managed extraction tools and the modern ELT architecture.
Chapter Quiz
Chapter Quiz — ETL & Data Pipelines
How data moves: ETL versus ELT, staging, idempotency, incremental loads and the gates that keep bad data out.
Question 1 of 5
A company just moved from on-premises SQL Server to Snowflake. Where should transformation happen?
Knowledge Check
End-of-Topic Exam
Hint: The knowledge check uses this exact scenario; changes must be identifiable after the last successful load.
Model answer: A full load rewrites the entire 500-million-row table every night, which is slow, costly and risks long lock windows. The incremental approach processes only new or changed rows since the last successful load, so the source must provide a change timestamp on each row, or a change data capture (CDC) feed identifying inserts and updates. The pipeline records a watermark (the maximum timestamp or log sequence number processed), extracts only rows beyond it, and merges or upserts them into the fact table. Answers that name how changes are identified gain full marks.
Hint: Where does the transformation run, and what does a scalable cloud warehouse change?
Model answer: ETL transforms inside middleware before loading; ELT loads raw data first and transforms inside the warehouse using SQL. For Snowflake I would recommend ELT because it leverages the warehouse's scalable compute for heavy transformation instead of being limited by a middleware server, and because transformations become version-controlled SQL, typically with dbt, that is easier to test and document. On-premises environments with strict pre-processing requirements would still favour ETL.
Hint: The word appears in the scheduling section and its callout.
Model answer: The property is idempotency: a pipeline must produce the same result whether it runs once or many times. Fix one: replace blind INSERT or append with a MERGE or UPSERT keyed on the natural order_id so re-processing updates rather than inserts. Fix two: rely on stable surrogate keys and add a uniqueness test on order_id plus a row-count reconciliation before and after the load, so any future duplication fails a quality gate and alerts the team.