skip to content

Azure Data Factory

Azure's managed integration service: pipelines of activities, linked services for connections, triggers for scheduling, and mapping data flows for no-code transformation. Interviewers ask how copy activities and data flows differ in what they actually run on.

on this pageshow

explore

questions

12

In Azure Data Factory, when do you need a Mapping Data Flow instead of a Copy activity?

level: juniorimportance: must knowfreq 78%

answer

  1. one moves bytes, one reshapes rows
  2. ask what has to start first
  3. joins and aggregates rule one of them out
  4. a Spark cluster has to be acquired
  5. land with Copy, transform in the flow

basics

~20 s

Use a Copy activity when you only move and land data. Use a Mapping Data Flow when you need real transformation - joins, aggregates, pivots, per-row insert/update logic - built visually and executed on a Spark cluster the service provisions.

solid answer

~50 s

The Copy activity is Azure Data Factory's movement primitive: source dataset to sink dataset, with column mapping, type and format conversion, and an optional source query. It cannot combine two independent inputs, aggregate, pivot, or decide per row whether something is an insert or an update. A Mapping Data Flow is the visual transformation designer - a graph of Source, Derived Column, Join, Aggregate, Alter Row and Sink transformations - which the service translates into Apache Spark work and runs on a cluster it acquires for you. That gives you Spark-scale transformation without writing Spark, but the cluster has to be acquired first, which costs minutes and cluster time. So: straight movement and format conversion stays in Copy; genuine reshaping goes to a data flow. A very common pipeline uses both - Copy to land raw data, then one data flow to transform it.

code

text · 7 lines
text
Pipeline: load_customer_dim
  [Copy]      sqldb.customers  ->  adls/raw/customers/@{utcnow('yyyyMMdd')}
  [Copy]      sqldb.addresses  ->  adls/raw/addresses/@{utcnow('yyyyMMdd')}
  [Data flow] df_customer_dim
        Source(raw/customers) --\
                                 Join(customer_id) -> DerivedColumn -> AlterRow -> Sink(dbo.dim_customer)
        Source(raw/addresses) --/

go deeper

for a junior

Be able to say the split in one line: Copy moves and lands data, a Mapping Data Flow reshapes it. Name two transformations Copy cannot do, such as joining two sources or aggregating.

for a middle

Explain the execution difference - Copy runs on the integration runtime and starts immediately, a data flow acquires a Spark cluster first - and why that makes data flows a poor fit for tiny, frequent jobs.

for a senior

Show the land-then-transform pattern and the connector and runtime limits that force it. Be ready to redesign a pipeline that spawns one data flow per table into Copy plus a single consolidated flow.

for a principal

Own the third option: transformation can also be pushed into the warehouse or an external engine while ADF only orchestrates. Frame the choice in terms of team skills, testability and where compute is already paid for.

## The two things you are choosing between Azure Data Factory ships two quite different ways of getting data somewhere useful, and interviewers ask this because picking the wrong one is the most common and most expensive ADF mistake. The **Copy activity** is the data-movement primitive. You give it a source dataset and a sink dataset and it streams rows from one store to the other. It has the widest connector surface in the service, it converts formats (delimited text to Parquet, JSON to tabular), it maps and renames columns and casts types in its mapping tab, and for many relational sources it lets you supply a query or a stored procedure so filtering and joining happen inside the source system before anything moves. What it will not do is take two independent inputs and combine them, group and aggregate, pivot, or mark a row as an update rather than an insert. A **Mapping Data Flow** is ADF's visual transformation designer. You build a directed graph - Source, Select, Derived Column, Filter, Conditional Split, Join, Lookup, Exists, Aggregate, Window, Pivot, Surrogate Key, Alter Row, Sink - and configure each node with expressions rather than code. At runtime the service compiles that graph into Apache Spark work and executes it on a Spark cluster that it provisions and manages. The whole point of the feature is Spark-scale transformation for people who do not want to write Spark. ## How the execution models differ A Copy activity runs as a data-movement job on an integration runtime. Its parallelism is expressed in Data Integration Units, the runtime is already available, and the activity begins moving rows almost immediately. A Data Flow activity does not do the work in the pipeline itself. It requests a Spark cluster whose shape comes from the data flow compute settings on the Azure integration runtime the activity runs on - compute type (general purpose, memory optimized, compute optimized) and core count. If no warm cluster is available for that integration runtime, acquiring one takes minutes before the first row is ever read, and you are paying for cluster time in core-hours while it runs. That asymmetry is the whole decision. Moving a 200-row lookup table with a data flow can spend minutes of cluster acquisition to do a few seconds of work, while a Copy activity would have finished before the cluster finished starting. ## A second, quieter difference: connector coverage The set of stores that a Mapping Data Flow can use as a source or sink is smaller than the set the Copy activity supports, and data flows run only on Azure integration runtimes. When your data lives somewhere a data flow cannot read - or behind a network boundary that needs a different runtime - the answer is not to abandon the transformation. It is to land the data first with a Copy activity into Blob Storage or ADLS Gen2, and point the data flow at the landed copy. This is the standard two-step shape and a good candidate says it without prompting. ## The third option nobody should forget There is always a third placement: let something else do the transformation and let ADF orchestrate it. A Stored Procedure or Script activity pushes SQL into a database or warehouse you are already paying for; a Databricks or Synapse notebook activity runs code your engineers can test. Mapping Data Flows sit between those and Copy: more capable than Copy, less capable and less testable than code, and worth their managed cluster only when the transformation genuinely needs a distributed engine and the team wants a visual surface. ## Choosing in practice - Pure movement, format conversion, column mapping, one source to one sink: **Copy activity**. - Many small tables to move on a schedule: a **ForEach over a parameterized Copy activity**, not one data flow per table. - Joining streams, deduplicating, aggregating, generating surrogate keys, driving upserts and deletes into a target table, and the team wants no code: **Mapping Data Flow**. - The transformation is already SQL and the target is a warehouse: push it down and let ADF orchestrate. - The logic needs libraries, unit tests and reviewable diffs: external compute. ## Cost shape, stated honestly Copy is billed on movement (Data Integration Unit time) plus activity runs. Data flows are billed on the cluster's core time. Neither is universally cheaper - a very large transformation that a data flow does in one pass can beat repeated Copy-and-stored-procedure round trips - but the fixed startup cost means a data flow's economics get worse the smaller and more frequent the job is. Consolidate: one data flow with several branches and several sinks costs one cluster acquisition, while five data flow activities cost up to five.

  • Can a Copy activity do any transformation at all?
    Some. Its mapping tab renames columns, converts types, converts formats, and can flatten a hierarchical source such as JSON into tabular output. For relational sources you can supply a query or stored procedure so filtering, joining and aggregation happen in the source system. What it cannot do is combine two independent inputs or apply per-row insert, update and delete decisions.
  • Your nightly load moves ten reference tables unchanged and deduplicates one fact table. How would you structure that in ADF?
    A ForEach over a parameterized Copy activity for the ten reference tables, and a single Mapping Data Flow for the deduplication - or land the fact table with Copy too and do the dedup in one data flow with the rest. The thing to avoid is one data flow per table: each activity can pay its own cluster acquisition to do seconds of work.
  • Where does a Data Flow activity's cluster configuration actually live?
    On the Azure integration runtime's data flow properties: compute type, core count and time to live. The Data Flow activity chooses which integration runtime to run on, so the same flow can run small on one runtime and large on another without editing the flow itself.

saying these in an interview costs you the question

  • Says a Copy activity can join two source tables together
  • Claims a Mapping Data Flow is just a UI over Copy
  • Wraps every small table move in its own data flow
  • Thinks a data flow runs inside the pipeline with no separate compute
  • Assumes every Copy connector is available as a data flow source

context

open as a page

In Azure Data Factory, how do a linked service, a dataset and an activity differ?

level: juniorimportance: must knowfreq 76%

basics

~20 s

In Azure Data Factory a linked service holds the connection and credentials for a store or compute, a dataset names the data inside it using that linked service, and an activity is the pipeline step that acts on the data.

open as a page

Why does an ADF Mapping Data Flow that processes 500 rows still take several minutes?

level: middleimportance: must knowfreq 55%

basics

~20 s

Nearly all of that time is cluster acquisition. A Data Flow activity must obtain a managed Spark cluster before reading a row. Set a time to live on the Azure integration runtime so later activities reuse a warm cluster.

open as a page

In Azure Data Factory, when would you choose a tumbling window trigger over a schedule trigger?

level: middleimportance: must knowfreq 70%

basics

~20 s

Choose the tumbling window trigger when each run owns a time slice: it fires once per contiguous, non-overlapping window, backfills every elapsed window from its start time, exposes the window boundaries to the pipeline, and supports concurrency limits, retries and dependencies.

open as a page

In an ADF Mapping Data Flow, why does Data preview require debug mode to be on?

level: juniorimportance: should knowfreq 48%

basics

~20 s

Data preview really executes the flow up to that transformation against live data. Debug mode starts a dedicated Spark cluster for your design session; without it there is no compute to run the sampled query on.

open as a page

In an ADF Mapping Data Flow, what must you configure for an Alter Row upsert to actually update rows?

level: middleimportance: should knowfreq 60%

basics

~20 s

Alter Row only tags each row as insert, update, upsert or delete. The sink must have the matching update method enabled and key columns set, or the tags are ignored and every run just inserts.

open as a page

In Azure Data Factory, when do you need a self-hosted integration runtime instead of the Azure one?

level: middleimportance: should knowfreq 62%

basics

~20 s

You need a self-hosted integration runtime when the source or sink is not reachable from the public Azure network — on-premises servers or private-network stores — because it runs as an agent inside your network and connects outbound to Azure Data Factory.

open as a page

In Azure Data Factory, why can a Set Variable inside a parallel ForEach produce wrong values?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Because pipeline variables are scoped to the whole pipeline run, not to a loop iteration. A ForEach runs its iterations in parallel by default, so concurrent Set Variable activities overwrite each other and later activities read whichever write landed last.

open as a page

In Azure Data Factory, how do you make each hourly tumbling window wait for the previous window?

level: seniorimportance: should knowfreq 46%

basics

~20 s

Add a self-dependency to the tumbling window trigger: a dependsOn entry of type SelfDependencyTumblingWindowTriggerReference with size equal to the window and a negative offset of one window, so each window waits for its predecessor to succeed.

open as a page

How do you decide between ADF Mapping Data Flows and an external engine for a team's transformations?

level: principalimportance: should knowfreq 35%

basics

~20 s

Weigh team skills, testability and where compute is already paid for. Mapping Data Flows suit low-code teams and moderate reshaping; warehouse SQL suits work the database can already do; notebooks or code win when logic needs libraries, tests and reviewable diffs.

open as a page

In an ADF Mapping Data Flow, when should you change the Optimize tab away from Use current partitioning?

level: seniorimportance: nice to knowfreq 38%

basics

~20 s

Rarely. The default lets the service manage partitioning. Override it to parallelize a database source read, to co-locate a key ahead of a heavy join or aggregate, to even out badly skewed data, or to force a single output file.

open as a page

In Azure Data Factory, why can a pipeline report Succeeded after its Copy activity failed?

level: seniorimportance: nice to knowfreq 35%

basics

~20 s

Because the pipeline's status is derived from the final activities that ran. If a failure-path activity handled the error and itself succeeded, the run ends with no failed leaf activity and Azure Data Factory reports the pipeline as Succeeded.

open as a page