Stage 3 summary. Engineering and platforms
Stage 3 takes data that has already been defined, modelled and measured, and asks a narrower question: how does it travel from the system that produced it to the moment a decision is taken, reliably enough that nobody has to check it by hand first. Pipelines, orchestrators, logs, databases, platforms and the tests over all of them are the answer, in the order a real platform acquires them.
One argument runs underneath every topic. Almost every decision here is a purchase with a price list: freshness is bought with operational complexity, consistency across a partition with availability, a managed platform with a switching cost, and a quality rule with the time somebody spends triaging it. The engineer's job is to know what is being bought, to say what it costs, and to buy it only where a decision would change.
Change is the normal condition, which is why reruns, versioning, promotion gates and contracts occupy as much of this stage as the movement of data.
What you carry out of this stage
- Draw the five-step engineering lifecycle and decide ETL against ELT on cost and control rather than fashion
- Design a step so that a rerun is harmless, and plan a bounded backfill through the same code path as the daily run
- Say what an orchestrator knows that a schedule cannot, and describe how a transformation change reaches production through environments and promotion gates
- Price freshness for a named decision, and choose between polling a table and reading its log
- State what at-most-once, at-least-once and exactly-once each cost the consumer, and design for the one you chose
- Tell warehouse, lake and lakehouse apart by operating model, and say why the catalogue layer became the control point
- Turn a quality dimension into an expectation with a subject, a threshold and a consequence, and read the core of a data contract
- Apply the leadership test that separates a data-product operating model from data-product vocabulary
Stage 3 route: the lifecycle and its undercurrents
Stage 3 teaches one chain, not seven tools: each module sits under the lifecycle link it teaches rather than in module order, and security, orchestration and the other undercurrents run under all five links and are finished by no one module.
Stage 3 teaches one chain, not seven tools: generation, ingestion, storage, transformation, serving. Each module is placed under the link it teaches, and the undercurrents that belong to no single link run as a band beneath the whole board.
The engineering lifecycle, the ETL or ELT decision, and why a rerun has to be harmless
Data engineering has a five-step shape: generation in the source systems, ingestion into the platform, storage, transformation, and serving to whoever or whatever consumes it. Generation almost always sits in systems the data team does not control, so the platform inherits their timing, outages and schema changes, while serving is where the value is finally claimed and every earlier step is judged by whether it made the last one trustworthy.
ETL transforms before the data lands in the destination; ELT loads it first and transforms inside the destination on that engine's compute. The decision is about cost and control, not fashion. ELT became common because elastic warehouse compute is often cheaper than a separate processing tier, and because a raw landing lets a team re-derive everything when a rule turns out to be wrong. ETL still wins where the destination is expensive to compute in, or where material must not land raw for legal reasons.
A step is idempotent when running it twice leaves the same result as running it once. Reruns are the normal case rather than an accident: a file arrives late, a node dies mid-write, a source issues a correction. So the design question is how to make a rerun uneventful, usually by replacing a whole partition deterministically rather than appending. Once that holds, a backfill is ordinary work: bound the range, push it through the daily job's own code path, and reconcile the periods that should not have moved.
Pipeline as a chain of contracts from source to serve
Only the rows the validate stage approves travel on to transform and serve, and the rejected ones go to quarantine with a reason and re-enter validate after repair, so a failure holds data back rather than losing it quietly.
A pipeline is a chain of explicit contracts, not a flat sequence of scripts. Source, ingest, validate, transform, serve each carry their own contract; failures route to quarantine and replay back into validate. Databricks medallion architecture names the same five-step shape.
An orchestrator knows the dependency a schedule can only imply, and DataOps makes a change ordinary
Cron answers one question: what should start at this time. It cannot express that this job depends on that one having finished, and the failure that follows is quiet rather than loud. A retailer's nine nightly jobs each started on time, found the previous day's file because the extract ran late, and reported success for eleven days. Every job was green and every number was stale, because a timetable had been asked to carry a dependency.
Apache Airflow 3.0, released on 22 April 2025, reads well as a statement about where the category went. DAG versioning ties a run to the code it started with, so a definition edited mid-run no longer produces a half-built execution. Event-driven scheduling lets work be triggered by data becoming ready. Data assets shift the unit of reasoning from the task to what the task produces. A task execution interface splits execution from the scheduler, so the orchestrator no longer hosts every dependency. Less timetable, more graph of assets that knows what is fresh.
The transformations themselves became code. Where models are select statements referring to each other rather than to hard-coded table names, the tool derives the build order, runs assertions beside the models they guard, publishes documentation from the same commit and produces lineage as a by-product. DataOps is what happens between that code and production: three environments running the same code against different targets, changed models and their descendants tested in a temporary schema on every pull request, and a promotion gate somebody believes.
Freshness is a purchase, the log is how it is delivered, and delivery semantics decide who cleans up
Batch against streaming is not a question about modernity. It asks how old the data may be when somebody or something acts on it, and what the wrong outcome costs. In a retailer most reporting is unharmed by seven-hour-old numbers, and the damage sits in a narrow band of decisions such as whether to show an item as in stock. Price those decisions and buy freshness only for them.
Underneath streaming sits the log: an append-only, ordered record that consumers read at their own position. A topic names a stream of those records, and a consumer group lets several processes share one topic's partitions without reading the same record twice. Apache Kafka 4.0, released on 18 March 2025, was the first major release to run entirely without ZooKeeper, making KRaft mode the default, so a cluster is one distributed system to operate rather than two. Share groups landed in the same release as an early access feature: a signal about direction rather than a foundation to settle payments on this year.
Most organisations do not emit events, they write database rows, and change data capture is how those rows become a stream. Polling a table for a modified timestamp loses deletes, misses intermediate states, depends on every writer maintaining the timestamp and applies analytical load to a transactional system; reading the database's own commit log avoids all four. The remaining question is what happens on a restart. At-most-once drops records, at-least-once duplicates them so consumers must be idempotent, and exactly-once holds only where the sink takes part in the guarantee.
Change data capture treats the transaction log as the source of truth
Change data capture reads the transaction log rather than the tables, so every consumer receives the same committed writes in the same order.
Change data capture reads the transaction log rather than the tables, so every consumer receives the same committed writes in the same order. Because the topic retains those records, a consumer can be rebuilt by replaying from a stored position instead of asking the source database again.
ACID has a price, CAP is narrower than the slogan, and the data model follows the workload
ACID names four guarantees a transaction can make: it happens completely or not at all, it leaves the data valid against its rules, it is not corrupted by transactions running alongside it, and once committed it survives a crash. Those guarantees are paid for with coordination, which costs latency and constrains how far a system can spread, so buying them everywhere by reflex is as much an error as refusing them.
The CAP intuition is routinely overstated. It says only that when a network partition happens, a distributed system must choose between refusing to answer and answering with data that may be stale. It says nothing about the far more common healthy case, where the real trade is between latency and how strictly reads reflect the most recent write.
Choose the data model from the workload rather than the label. Relational fits data of stable shape queried by joining it and written transactionally, document fits records of varying shape usually read whole, key-value fits lookup by a known key at high rates, and graph fits work where the relationships are the query. An in-process engine such as DuckDB has then moved the boundary underneath all four: much of what was called big data was a cluster answer to a laptop-sized question.
Warehouse, lake and lakehouse differ by operating model, and the catalogue became the control point
The three platform shapes are best told apart by who operates what. A warehouse manages storage and engine together, giving strong guarantees in exchange for accepting its format and its bill. A lake is files in object storage that you own outright and that guarantee nothing on their own. A lakehouse puts an open table format over those files so they behave like warehouse tables while the storage stays yours.
The table format is the whole trick. Apache Iceberg and comparable formats add a metadata layer above columnar files, supplying atomic commits, schema evolution without rewriting history, snapshot reads and safe concurrent readers and writers. Once tables are open, the engine stops being the thing that holds the data, which is why the catalogue layer became the point of leverage between 2024 and 2026: it is where the decision about which engine may read which table, under whose permissions, now lives.
The major platforms are best compared as operating models rather than feature lists: how compute is billed and isolated, how governance is expressed, and what leaving would cost. DuckLake, zero-ETL services and reverse ETL each remove a piece of pipeline without removing the modelling, quality or contract work that made it meaningful. Medallion, with its bronze, silver and gold layers, is a naming convention for degrees of refinement, and calling a layer gold does not make anything in it true.
The lakehouse stack turns on who controls the catalogue layer
A query descends from engine to catalogue to table format to bytes, and the engines are the layer that swaps out easily, so whoever holds the catalogue holds the permissions, the cost and the lock-in.
A lakehouse query descends four layers: the engine asks the catalogue, the catalogue names the table, the open table format finds the files, and object storage returns the bytes. The engines are the easy layer to swap, which is why the catalogue is the layer that is fought over.
A dimension becomes a control only when it has a subject, a threshold and a consequence
Stage 1 established what quality dimensions mean. Making one executable takes three additions: a subject, meaning this dataset and this column; a threshold, so not complete but no more than half a per cent of rows missing a postcode over a daily batch; and a consequence, deciding whether a breach blocks the release, quarantines the batch or raises a warning. A rule with no consequence is documentation with a schedule attached.
Testing and observability are different jobs and neither substitutes for the other. A test asserts something you predicted; observability watches the shape of the data for what nobody predicted. The clearest case is an operational team reusing a status code so one value quietly acquires a second meaning: every assertion anyone had written stayed true, while a monitor on the distribution would have shown that code jump from two per cent of rows to eleven overnight.
A data contract is where the promise is written down: schema, service levels for freshness and availability, quality rules with thresholds, a named owner, and the policy for breaking changes. The Open Data Contract Standard gives that promise a platform-agnostic shape. What makes a contract real is that it lives in version control and is checked on every pull request, so a change that would break a stated consumer fails before it merges.
The same silent change, found by a consumer or by a monitor
A silent change, where the meaning moves but the declared type does not, passes every assertion in both lanes, so the tested-only pipeline is repaired by a consumer after the harm lands and the observed one by the producer in the same run.
A test proves an assertion still holds; observability notices that the data stopped looking like itself. Run the same silent schema change down both lanes and the tested-only pipeline is repaired by a consumer after the harm lands, while the observed pipeline is repaired by the producer in the same run.
Data as a product is four operating commitments, and the leadership test is whether accountability moved
Zhamak Dehghani set out data mesh in 2019 and 2020 as a sociotechnical pattern for scaling analytical data, arguing that one central team cannot hold every domain's meaning, quality and change cadence. Its four principles are commitments rather than labels: domain teams own the analytical data they produce, including its meaning and change control; those outputs run as products with documented consumers, service levels, versioning and a support route; a shared self-serve platform stops each team rebuilding infrastructure; and governance is federated, decided centrally and enforced through code, tests and platform controls.
The leadership test is short: ask who fixed the last three data incidents in a named domain. If the central team still fixes everything while domain teams attend workshops, the organisation has taken the vocabulary and not the operating model. Ownership with no budget, no on-call and no authority to refuse a request is a diagram.
This is also where contracts stop being a quality device and become the product's interface, stating what a consumer receives and what the producer guarantees. The post-hype reading is that mesh is worth adopting where domain ownership solves a scaling problem the organisation can actually name, and that a small team can take the product thinking, the ownership and the contract without taking the bureaucracy.
The traps this stage warns against
Treating a rerun as an exception, so pipeline steps append rather than replace and a second run silently doubles the numbers.
Instead: Assume reruns are ordinary. Make each step idempotent by writing a deterministic key or replacing a whole partition, and prove it by running the step twice in staging and comparing the output.
Reading nine green job statuses as evidence that the data is current.
Instead: A schedule reports that a job started and finished, not that its input was fresh. Express the dependency in an orchestrator and alert on the freshness of the data asset rather than on the exit code of the task.
Choosing streaming for the whole platform because a handful of decisions need fresher data.
Instead: Name the decisions whose outcome changes with the age of the data, price the wrong outcome, and buy low latency only for those paths. Leave the rest on the cheap, restartable overnight run.
Assuming at-least-once delivery means nothing arrives twice, and building consumers that add up whatever they receive.
Instead: At-least-once guarantees no loss, not no duplication. Give every event a stable key, make the consumer idempotent, and only claim exactly-once where the sink itself participates in the guarantee.
Writing quality dimensions into a policy document and calling that a quality programme.
Instead: Attach each dimension to a named dataset and column, give it a numeric threshold and a stated consequence on breach, put it in version control, and run it on every change.
Renaming existing datasets as data products while the central team still owns every fix.
Instead: Move accountability with the label. A data product needs a named owner with budget and on-call, a published contract, a service level and a route for consumer feedback, or the change is cosmetic.
Core distinctions
- ETL transforms before the destination and ELT transforms inside it, and the choice turns on the cost of compute and the need to keep a raw landing, not on which is newer
- Idempotency is a property of a step, not of a pipeline: running it twice must leave what running it once left, which is what makes a backfill routine rather than risky
- A scheduler expresses when a job starts; an orchestrator expresses what a job depends on, which version of the code produced a run, and whether the data it needed is fresh
- Change data capture reads the database's own commit log, so it sees deletes and intermediate states that polling a modified timestamp will always miss
- At-most-once loses records, at-least-once duplicates them, and exactly-once is an end-to-end property that requires the sink to take part rather than a setting on the producer
- A warehouse manages storage and engine together, a lake is files you own with no guarantees, and a lakehouse is an open table format that gives lake files warehouse behaviour
- Testing asserts what you predicted and fails when it stops holding; observability detects the change nobody wrote a rule for, which is why a fully passing test suite is not evidence of healthy data
- A data product is a commitment to owner, contract, service level and support; the word applied to an unchanged dataset with an unchanged owner is vocabulary rather than an operating model
That is Stage 3 in one place: a lifecycle whose reruns are safe, orchestration that knows dependencies rather than start times, freshness bought only where a decision changes, storage and platform choices made on operating model, and quality rules and contracts that run in the pipeline instead of sitting in a document. The scenario practice now puts those judgements under pressure with situations where the cheap answer and the correct answer differ, before Stage 4 asks what all of this has to look like when the consumer is a model rather than a person.
Sources and further reading
- Apache Airflow 3.0 release announcementThe 22 April 2025 release behind the orchestration section, covering DAG versioning, event-driven scheduling, data assets and the task execution interface.
- Apache IcebergThe open table format behind the lakehouse section, supplying atomic commits, schema evolution and snapshot reads over files in object storage you own.
- Open Data Contract Standard (Bitol)The platform-agnostic shape a data contract takes: fundamentals, schema, quality rules, service levels, roles and support.
- Data Mesh Principles and Logical Architecture (Dehghani, 2020)The primary statement of the four principles read here as operating commitments rather than labels.
- Fivetran and dbt Labs complete mergerThe vendor consolidation of 2025 and 2026 that makes the open-standard hedges in this stage a procurement question rather than a preference.
- AWS Well-Architected Framework, Data Analytics LensA worked vendor treatment of the platform trade-offs in this stage: ingestion, storage, cost and operational burden read together.