Azure Data Factory Triggers Explained: Schedule, Tumbling Window, and Event-Based Triggers

Azure Data Factory Triggers Explained: Schedule, Tumbling Window, and Event-Based Triggers

You built the pipeline. It works perfectly in Debug mode. But how do you make it run automatically at 2 AM every day? Or trigger it when a file lands in your data lake? Or process data in hourly windows that never miss a beat?

That is what triggers do. They are the scheduling and event engine of Azure Data Factory and Synapse Pipelines. And choosing the wrong trigger type is one of the most common mistakes in production pipeline design.

This guide covers all three trigger types with real-world scenarios, step-by-step setup, and the critical differences that determine which one to use.

Table of Contents

  • What Are Triggers?
  • The Three Trigger Types
  • Schedule Trigger
  • Tumbling Window Trigger
  • Event-Based Trigger (Storage Events)
  • Comparison Table: All Three Types
  • Trigger Parameters: Passing Data to Pipelines
  • Managing Triggers: Start, Stop, and Monitor
  • Common Trigger Patterns
  • Trigger vs Debug vs Manual Run
  • Common Mistakes
  • Interview Questions
  • Wrapping Up

What Are Triggers?

A trigger defines when a pipeline runs. Without a trigger, pipelines only run when you manually click Debug or Trigger Now.

Triggers are separate resources from pipelines. One trigger can start one or more pipelines. One pipeline can have multiple triggers. They are loosely coupled.

Trigger: TR_Daily_2AM (Schedule)
  |-- starts PL_Copy_SqlToADLS
  |-- starts PL_Cleanup_OldFiles

Trigger: TR_FileArrival (Event)
  |-- starts PL_Process_NewFile

Pipeline: PL_Copy_SqlToADLS
  |-- triggered by TR_Daily_2AM (schedule)
  |-- triggered by TR_Hourly_Refresh (another schedule)
  |-- can also be run manually

The Three Trigger Types

Type Fires When Best For
Schedule At a fixed time/interval Daily ETL, hourly refreshes, weekly reports
Tumbling Window At a fixed time/interval WITH state tracking Time-series processing, guaranteed exactly-once per window
Event-Based When a file is created/deleted in storage File-driven ingestion, real-time-ish processing

Schedule Trigger

What It Does

Fires at a fixed schedule — daily, hourly, every 15 minutes, specific days of the week, etc. This is the simplest and most commonly used trigger.

When to Use

  • Daily ETL pipeline at 2 AM
  • Hourly data refresh
  • Weekly report generation
  • Any fixed-schedule recurring job

Setting Up a Schedule Trigger

  1. Open your pipeline in ADF/Synapse Studio
  2. Click Add trigger > New/Edit
  3. Click + New
  4. Configure:
  5. Name: TR_Daily_2AM
  6. Type: Schedule
  7. Start date: 2026-04-07T02:00:00Z
  8. Recurrence: Every 1 Day
  9. Time zone: Eastern Standard Time (or your preferred zone)
  10. End date: No end (or set a specific end date)
  11. Click OK > Publish

Advanced Schedule Options

Run at specific times:

Every day at 2:00 AM, 8:00 AM, and 6:00 PM
Recurrence: 1 Day
At these hours: 2, 8, 18
At these minutes: 0

Run on specific days:

Every Monday and Friday at 9:00 AM
Recurrence: 1 Week
On these days: Monday, Friday
At these hours: 9

Run every 15 minutes during business hours:

Recurrence: 1 Day
At these hours: 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
At these minutes: 0, 15, 30, 45

Schedule Trigger Limitations

  • No state tracking — if the pipeline fails, the trigger does not know. The next scheduled run simply starts on time regardless.
  • No backfill — if the trigger was paused for 3 days, it does not catch up on missed runs.
  • No dependency — cannot wait for a previous run to complete before starting the next one.

Tumbling Window Trigger

What It Does

Similar to Schedule but with state tracking per time window. Each window is an independent, non-overlapping time slice that is processed exactly once.

When to Use

  • Processing data in fixed time windows (hourly, daily) where every window MUST be processed
  • When you need backfill — catch up on missed windows
  • When you need dependency chaining — one pipeline’s window depends on another’s
  • Time-series data processing where gaps are not acceptable

How It Differs from Schedule

Schedule Trigger:
  2 AM: Run pipeline --> FAILED
  2 AM next day: Run pipeline (no retry of yesterday's failure)
  Result: Yesterday's data is LOST unless manually rerun

Tumbling Window Trigger:
  Window [2026-04-07 00:00, 2026-04-08 00:00]: Run pipeline --> FAILED
  Automatic retry: Rerun the failed window
  Window [2026-04-08 00:00, 2026-04-09 00:00]: Run normally
  Result: Every window is processed, no data loss

Setting Up a Tumbling Window Trigger

  1. Click Add trigger > New/Edit > + New
  2. Configure:
  3. Name: TR_Hourly_Window
  4. Type: Tumbling Window
  5. Start date: 2026-04-01T00:00:00Z
  6. Recurrence: Every 1 Hour
  7. Max concurrency: 1 (process one window at a time)
  8. Retry policy: 3 retries with 15-minute intervals
  9. Delay: 0 minutes (start immediately when window opens)
  10. Click OK > Publish

Tumbling Window Parameters

The trigger automatically provides window start and end times to the pipeline:

@trigger().outputs.windowStartTime  -->  "2026-04-07T00:00:00Z"
@trigger().outputs.windowEndTime    -->  "2026-04-07T01:00:00Z"

Use these in your pipeline to process only the data for that specific window:

SELECT * FROM orders
WHERE order_date >= '@{trigger().outputs.windowStartTime}'
  AND order_date < '@{trigger().outputs.windowEndTime}'

Backfill with Tumbling Window

If you create a trigger with a start date in the past:

Start date: 2026-01-01
Current date: 2026-04-07
Recurrence: Daily

The trigger automatically creates windows for every day from Jan 1 to Apr 7 and starts processing them. This is automatic backfill — no manual intervention needed.

Window Dependencies

Tumbling Window triggers support dependencies between pipelines:

Pipeline A (hourly window) must complete before Pipeline B starts for the same window

TR_Window_A: Process raw data for [00:00-01:00]
TR_Window_B: Depends on TR_Window_A, transforms data for [00:00-01:00]

Configure in the trigger’s dependency settings.

Tumbling Window Concurrency

Max concurrency = 1: Windows are processed one at a time, in order. Safest option.

Max concurrency = 5: Up to 5 windows can process simultaneously. Faster for backfill but requires idempotent pipelines.

Event-Based Trigger (Storage Events)

What It Does

Fires when a file is created or deleted in Azure Blob Storage or ADLS Gen2. The pipeline starts automatically when data arrives.

When to Use

  • Process files as soon as they land in the data lake
  • Ingest data from external systems that drop files on a schedule
  • React to upstream pipeline outputs
  • Near-real-time file processing

Setting Up an Event-Based Trigger

  1. Click Add trigger > New/Edit > + New
  2. Configure:
  3. Name: TR_NewFile_Bronze
  4. Type: Storage events
  5. Storage account: select your ADLS Gen2 account
  6. Container: datalake
  7. Blob path begins with: bronze/incoming/
  8. Blob path ends with: .parquet
  9. Event: Blob created
  10. Ignore empty blobs: Yes
  11. Click OK > Publish

Event Trigger Parameters

The trigger provides the file details to the pipeline:

@trigger().outputs.body.folderPath   --> "bronze/incoming/"
@trigger().outputs.body.fileName     --> "customers_20260407.parquet"

Use these to process the specific file that triggered the pipeline:

Copy Activity Source:
  FolderPath: @trigger().outputs.body.folderPath
  FileName: @trigger().outputs.body.fileName

Filtering Events

You can filter which files trigger the pipeline:

Blob path begins with: bronze/incoming/     (only files in this folder)
Blob path ends with: .parquet               (only Parquet files)

This prevents the pipeline from triggering on temp files, logs, or irrelevant uploads.

Event Trigger Requirements

  • Storage account must have Event Grid resource provider registered
  • ADF/Synapse needs appropriate permissions on the storage account
  • There is a slight delay (seconds to a minute) between file creation and trigger firing
  • If multiple files arrive simultaneously, the trigger fires for EACH file

Comparison Table: All Three Types

Feature Schedule Tumbling Window Event-Based
Fires on Fixed time/interval Fixed time/interval File created/deleted
State tracking No Yes (per window) No
Backfill No Yes (automatic) No
Retry failed windows No Yes (configurable) No (pipeline retry only)
Window parameters No Yes (windowStart, windowEnd) No (file info instead)
Dependencies No Yes (between triggers) No
Concurrency control No (overlapping runs possible) Yes (max concurrency) Limited
File info to pipeline No No Yes (folder, fileName)
Best for Simple scheduled ETL Time-series, guaranteed processing File-driven ingestion
Complexity Low Medium Medium

Trigger Parameters: Passing Data to Pipelines

Schedule Trigger Parameters

Schedule triggers can pass static parameters to pipelines:

{
    "parameters": {
        "environment": "production",
        "sourceSchema": "SalesLT"
    }
}

Tumbling Window Parameters

Access window times in the pipeline:

Pipeline parameter: windowStart = @trigger().outputs.windowStartTime
Pipeline parameter: windowEnd = @trigger().outputs.windowEndTime

Event Trigger Parameters

Access file details in the pipeline:

Pipeline parameter: folderPath = @trigger().outputs.body.folderPath
Pipeline parameter: fileName = @trigger().outputs.body.fileName

Managing Triggers: Start, Stop, and Monitor

Starting a Trigger

After creating and publishing a trigger, it must be started:

  1. Go to Manage > Triggers
  2. Find your trigger
  3. Click the Start button (or toggle)

A trigger that is created but not started will not fire.

Stopping a Trigger

Before deploying changes via CI/CD, stop all triggers first:

az datafactory trigger stop     --resource-group rg-dev     --factory-name adf-dev     --name TR_Daily_2AM

This prevents pipelines from running during deployment. Restart after deployment completes.

Monitoring Trigger Runs

  1. Go to Monitor > Trigger runs
  2. See which triggers fired, when, and which pipelines they started
  3. Filter by status (Succeeded, Failed, In Progress)

Common Trigger Patterns

Pattern 1: Daily ETL with Notification

TR_Daily_2AM (Schedule, daily at 2 AM)
  |-- PL_Daily_ETL
      |-- Copy all tables
      |-- Run audit logging
      |-- Web Activity: send Slack notification with results

Pattern 2: Hourly Incremental with Tumbling Window

TR_Hourly_Window (Tumbling Window, every 1 hour)
  |-- PL_Incremental_Load
      |-- Uses @trigger().outputs.windowStartTime as the delta range
      |-- Processes only data from that specific hour
      |-- Guaranteed: every hour is processed exactly once

Pattern 3: File Landing Zone

TR_NewFile (Event, blob created in /incoming/*.csv)
  |-- PL_Process_File
      |-- Copy file from /incoming/ to /bronze/ (with date partition)
      |-- Delete original from /incoming/
      |-- Log processing result

Pattern 4: Multi-Trigger Pipeline

PL_Copy_SqlToADLS is triggered by:
  - TR_Daily_2AM (daily at 2 AM for full refresh)
  - TR_Manual (via REST API for ad-hoc runs)
  - TR_Upstream_Complete (when upstream pipeline finishes)

Trigger vs Debug vs Manual Run

Method When to Use Parameters Monitored
Debug Development and testing Manually entered Yes (output pane)
Trigger Now One-time manual run Manually entered Yes (Monitor tab)
Trigger (scheduled) Automated production runs From trigger config Yes (Monitor tab)

Debug runs are NOT captured in the Monitor tab’s Pipeline runs section (they appear in Debug output only). Trigger Now and scheduled triggers appear in Monitor.

Common Mistakes

1. Forgetting to Start the Trigger

Creating and publishing a trigger does not start it. You must explicitly start it.

2. Overlapping Schedule Trigger Runs

If a pipeline takes 2 hours but the schedule trigger fires every hour, multiple instances run simultaneously:

2 AM: Pipeline starts (takes 2 hours)
3 AM: Pipeline starts again (previous still running)
Result: Two copies writing to the same destination simultaneously

Fix: Use Tumbling Window trigger with max concurrency = 1, or add a check at the start of the pipeline.

3. Not Stopping Triggers Before CI/CD Deployment

Triggers firing during ARM template deployment can cause failures. Always stop triggers in the pre-deployment script and restart in post-deployment.

4. Event Trigger Firing for Every File

If a Spark job writes 100 Parquet files to a folder, the event trigger fires 100 times. Each file creates a separate pipeline run.

Fix: Filter by specific file names (e.g., _SUCCESS file) or use a Schedule/Tumbling Window trigger instead.

5. Not Using Tumbling Window for Time-Series Data

Using a Schedule trigger for hourly processing means missed hours are lost. Tumbling Window automatically retries failed windows and backfills gaps.

Interview Questions

Q: What are the three trigger types in ADF? A: Schedule (fixed time/interval), Tumbling Window (time-based with state tracking and backfill), and Event-Based (fires when a file is created/deleted in storage).

Q: When would you use a Tumbling Window trigger instead of a Schedule trigger? A: When you need guaranteed processing of every time window, automatic retry of failed windows, backfill for historical data, or dependency chaining between pipelines. Tumbling Window tracks state per window; Schedule does not.

Q: How does an Event-Based trigger work? A: It monitors an Azure Storage container for file creation or deletion events. When a matching file appears (based on path prefix and suffix filters), the trigger fires and passes the file path and name to the pipeline as parameters.

Q: What happens if a Schedule trigger fires while the previous run is still executing? A: A new pipeline run starts regardless. This can cause concurrent runs writing to the same destination. Use Tumbling Window with max concurrency = 1 to prevent this.

Q: How do you pass the window time range to a pipeline from a Tumbling Window trigger? A: Use @trigger().outputs.windowStartTime and @trigger().outputs.windowEndTime as pipeline parameters. The pipeline uses these to query only the data for that specific window.

Q: Why must you stop triggers before CI/CD deployment? A: Triggers firing during deployment can run pipelines with half-deployed resources, causing failures or data corruption. Stop all triggers in pre-deployment, deploy, then restart in post-deployment.

Wrapping Up

Choosing the right trigger type is critical for production pipelines:

  • Schedule for simple, fixed-time runs where missed runs are acceptable
  • Tumbling Window for time-series processing where every window must be processed
  • Event-Based for file-driven ingestion where you react to data arrival

Most production data platforms use a combination of all three. Master them, and your pipelines run reliably without manual intervention.

Related posts:What is Azure Data Factory?Metadata-Driven Pipeline in ADFIncremental Data LoadingCI/CD with GitHubTop 15 ADF Interview Questions


Naveen Vuppula is a Senior Data Engineering Consultant and app developer based in Ontario, Canada. He writes about Python, SQL, AWS, Azure, and everything data engineering at DriveDataScience.com.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top
Share via
Copy link