In Azure Data Factory, when would you choose a tumbling window trigger over a schedule trigger?
answer
- one fires on the clock, one on windows
- only one of them replays the past
- runs get their own start and end times
- concurrency, retry and dependencies live on the trigger
basics
~20 sChoose 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.
solid answer
~40 sA **schedule trigger** is wall-clock only: it fires at the recurrence you configure, can start many pipelines and be attached to many, and it does **not** replay periods that elapsed before it was started. All the pipeline gets is `@trigger().scheduledTime`. A **tumbling window trigger** models the data as fixed-size, contiguous, non-overlapping windows. It binds to exactly one pipeline, and if its `startTime` is in the past it immediately creates one run per elapsed window — that is ADF's backfill mechanism. Each run receives `@trigger().outputs.windowStartTime` and `@trigger().outputs.windowEndTime`, so the pipeline can filter its source to its own slice, and the trigger adds `maxConcurrency`, a `retryPolicy`, a `delay` and dependencies on other tumbling window triggers. Use tumbling windows for incremental, re-runnable loads; schedule triggers for "just run this at 6am".
code
json · 20 lines{
"name": "DailyAt2am",
"properties": {
"type": "ScheduleTrigger",
"typeProperties": {
"recurrence": {
"frequency": "Day",
"interval": 1,
"startTime": "2026-08-01T02:00:00Z",
"timeZone": "UTC"
}
},
"pipelines": [
{
"pipelineReference": { "referenceName": "LoadOrders", "type": "PipelineReference" },
"parameters": { "runAt": "@trigger().scheduledTime" }
}
]
}
}go deeper
Know that triggers are separate objects from pipelines and be able to name the schedule, tumbling window and storage event kinds without mixing them up.
Explain the mechanical difference: a clock instant versus a contiguous window, many-to-many versus one-to-one binding, and which one replays elapsed periods when started with a past start time.
Justify the choice for a real load — window boundaries as parameters, maxConcurrency to keep a backfill from flooding the source, delay for late files, and a reconciliation path when events are involved.
Own the estate-level policy: which trigger type is the default for incremental loads, how backfills are authorised and throttled, and how freshness SLAs are detected when no run was ever created.
## What a trigger is in ADF A trigger is a separate object from the pipeline. It decides *when* a pipeline run is created and *what parameter values* that run receives. ADF offers four kinds: **schedule**, **tumbling window**, **storage event**, **custom event** — plus manual invocation from the portal, PowerShell, the SDKs or the REST API. ## Schedule trigger A schedule trigger carries a `recurrence` block: `frequency` (Minute, Hour, Day, Week, Month), `interval`, `startTime`, an optional `endTime`, a `timeZone`, and for weekly/monthly a `schedule` sub-block naming hours, minutes, weekdays or month days. Two properties matter for interviews: - Its relationship to pipelines is **many-to-many**: one trigger can start several pipelines, and a pipeline can be started by several triggers. - It has **no notion of a data interval**. Starting a schedule trigger whose `startTime` is a week in the past does not produce a week of runs; it simply begins firing at the next valid occurrence. The only time value it hands over is `@trigger().scheduledTime` (with `@trigger().startTime` available too), which is a clock instant, not a window. Time zone handling is a real trap: recurrence honours the configured `timeZone`, and daylight-saving transitions can move a run relative to UTC, which matters when a downstream system expects a fixed UTC hour. ## Tumbling window trigger A tumbling window trigger slices time into fixed-size, contiguous, non-overlapping windows starting at `startTime`, with `frequency` and `interval` defining the size. Its distinguishing traits: - **One trigger, one pipeline.** The binding is 1:1, which is what lets ADF track per-window state. - **Backfill by construction.** Set `startTime` in the past and, once started, the trigger creates a run for every window that has already elapsed, subject to `maxConcurrency` (how many windows may be in flight at once). This is how you reload three months of history without writing a loop. - **Window boundaries are parameters.** `@trigger().outputs.windowStartTime` and `@trigger().outputs.windowEndTime` are passed into pipeline parameters, and the pipeline filters its source with them. This is what makes each run deterministic and safe to rerun. - **Per-window retry.** `retryPolicy` with `count` and `intervalInSeconds` retries the window itself, independent of any retry configured on individual activities. - **`delay`.** A delay postpones the start of the run after the window closes — useful when the upstream file lands a few minutes late. It does *not* move the window boundaries and does not shift subsequent windows. - **Dependencies.** A tumbling window trigger can depend on other tumbling window triggers, or on itself, so windows run in order or wait for upstream slices. - **Per-window monitoring and rerun.** Trigger runs are listed individually and a single window can be rerun without touching its neighbours. ```json { "type": "TumblingWindowTrigger", "typeProperties": { "frequency": "Hour", "interval": 1, "startTime": "2026-08-01T00:00:00Z", "delay": "00:10:00", "maxConcurrency": 4 } } ``` ## Event triggers A **storage event trigger** fires when a blob is created or deleted in a Blob Storage or ADLS Gen2 account, filtered by `blobPathBeginsWith` / `blobPathEndsWith`. It is delivered through Azure Event Grid, so the Event Grid resource provider must be registered on the subscription and the factory's identity needs rights on the storage account. The pipeline receives `@triggerBody().folderPath` and `@triggerBody().fileName` — the *path*, never the contents. A **custom event trigger** does the same for events published to an Event Grid custom topic, exposing the event payload through `@triggerBody().event…`. Event triggers are the right choice when arrival is irregular and you want low latency. They are the wrong choice when you need one deterministic run per period, because you cannot easily backfill an event that never fired. ## Choosing Ask what the run is *for*. If a run owns a slice of data and must be replayable — hourly incremental loads, daily partitions, anything you might backfill — use a tumbling window trigger and pass the boundaries in. If the pipeline is time-driven but stateless (send a report, refresh a full-load dimension, kick off housekeeping), a schedule trigger is simpler and can drive several pipelines. If work should start when a file lands, use a storage event trigger, and keep the pipeline idempotent because event delivery is not something you control. One mixed pattern is common: a storage event trigger for the fast path plus a tumbling window trigger over the same data as a safety net that reconciles any window whose event was missed. ## Version note This describes Azure Data Factory V2, the current service. ADF V1 used a different, dataset-slice-driven scheduling model, and answers that reach for "dataset availability" are describing a product that is no longer what candidates are asked about.
- What does the delay property on a tumbling window trigger do?It postpones the start of the run until the given amount of time after the window closes, which lets late-arriving source files land first. It does not change windowStartTime or windowEndTime, and it does not shift later windows — the slicing of time stays fixed.
- Can two different triggers start the same pipeline?Schedule and event triggers are many-to-many, so yes. A tumbling window trigger binds to exactly one pipeline. When several triggers can start one pipeline, branch on @pipeline().TriggerType or @pipeline().TriggerName so the run knows which path it is on.
- How do you rerun just one bad day of a tumbling-window-driven load?Find that window in the trigger runs view in Monitor and rerun it; the run receives the same window boundaries, so an idempotent pipeline overwrites the day cleanly. For a schedule-triggered pipeline there is no window state, so you invoke the pipeline manually with the date as a parameter.
- Why is a storage event trigger a poor fit for a strict daily SLA?Because the run only exists if an event arrived. A missed or unfired event leaves a silent gap with nothing to rerun. Teams that need the SLA pair the event trigger with a tumbling window trigger that reconciles each period, or add a completion check that alerts when a window produced no run.
saying these in an interview costs you the question
- Says a schedule trigger backfills when its start time is in the past
- Attaches one tumbling window trigger to several pipelines
- Thinks a schedule trigger exposes the interval start and end
- Expects a storage event trigger to deliver the file contents
- Treats trigger retry and activity retry as the same setting