# Triggers

### from zenml.config.pipeline\_run\_configuration import PipelineRunConfiguration--- description: Trigger pipelines by schedule or event. icon: server

## Triggers

{% hint style="info" %}
Triggers are part of ZenML's paid features. For details on availability and supported plans, visit the [pricing page](https://www.zenml.io/pricing)
{% endhint %}

In the [snapshots](https://docs.zenml.io/pro/core-concepts/snapshots) section, you learned how to prepare snapshots and execute them on demand via the dashboard, CLI, or SDK. In many cases, however, pipelines need to run automatically - either on a schedule or in response to an event.

Triggers enable this behavior. A Trigger is a configuration that defines one or more events that automatically start a pipeline.

### Schedule Triggers

*Schedule* triggers enable users to define and manage an execution schedule. See below a comprehensive list of the schedule configuration options:

| Attribute              | Description                                                  | Notes                        |
| ---------------------- | ------------------------------------------------------------ | ---------------------------- |
| name                   | The name of the schedule                                     | Unique within project        |
| cron\_expression       | A cron expression describing your schedule's frequency       | Standard 5-field cron format |
| interval               | An interval (in seconds) describing the schedule's frequency | Combined with start\_time    |
| run\_once\_start\_time | One-off execution at a specific time in the future           | UTC                          |
| start\_time            | The beginning of the schedule                                | UTC                          |
| end\_time              | The end time of the schedule                                 | UTC                          |
| active                 | Status of the schedule (active/inactive)                     | -                            |
| concurrency            | Option to control how concurrent runs should be handled      | Skip is the default option   |

#### Create a schedule

Let's start by creating a schedule. We can do so, via the SDK or the CLI.

Via the SDK:

```python
from zenml.client import Client
from zenml.enums import TriggerRunConcurrency

client = Client()

daily_schedule = client.create_schedule_trigger(
    name='daily-schedule-6-am',
    cron_expression='0 6 * * *',
    active=True,
    concurrency=TriggerRunConcurrency.SKIP,
)
```

Via the CLI:

```bash
zenml trigger schedule create daily-schedule-6-am --cron-expression "0 6 * * *"
```

#### Attach/Detach schedules and snapshots

So far we have instructed our system with *when* to execute but not *what*. To do so, we need to *attach* a schedule to a snapshot.

Via the SDK:

```python
from zenml.client import Client

client = Client()
client.attach_trigger_to_snapshot(
    trigger_id="<TRIGGER_ID>",
    pipeline_snapshot_id="<>SNAPSHOT_ID"
)
```

Via the CLI:

```bash
zenml trigger schedule attach "<TRIGGER_ID>" "<SNAPSHOT_ID>"
```

Users can provide a configuration object to define the parameters of pipeline runs triggered from this attachment.

Via the SDK:

```python
from zenml.client import Client
from zenml.config.pipeline_run_configuration import PipelineRunConfiguration

client = Client()
client.attach_trigger_to_snapshot(
    trigger_id="<TRIGGER_ID>",
    pipeline_snapshot_id="<>SNAPSHOT_ID",
    run_configuration=PipelineRunConfiguration(
        enable_step_logs=True,
        enable_pipeline_logs=True,
    )
)
```

Via the CLI:

```bash
zenml trigger schedule detach "<TRIGGER_ID>" "<SNAPSHOT_ID>" --config=<path-to-your-config>.yml
```

Triggers can be *detached* from snapshots as well.

Via the SDK:

```python
from zenml.client import Client

client = Client()
client.detach_trigger_from_snapshot(
    trigger_id="<TRIGGER_ID>",
    pipeline_snapshot_id="<>SNAPSHOT_ID"
)
```

Via the CLI:

```bash
zenml trigger schedule detach "<TRIGGER_ID>" "<SNAPSHOT_ID>"
```

The ability to detach and attach snapshots is particularly useful as pipelines evolve. When a new pipeline version becomes available, you can update the schedule to use it by detaching the previous snapshot and attaching the new one.

As with on-demand execution, scheduling requires snapshots with a \*\*remote stack\*\* with at least: - Remote orchestrator - Remote artifact store - Container registry

#### Update schedules

You can update a schedule's configuration at any point. In the example, we will de-activate and rename the schedule.

Via the SDK:

```python
from zenml.client import Client

client = Client()
client.update_schedule_trigger(
    trigger_id="<TRIGGER_ID>",
    active=False,
    name="daily-schedule-6-am[DO NOT TOUCH]"
)
```

Via the CLI:

```bash
zenml trigger schedule update "<TRIGGER_ID>" --active=false --name="daily-schedule-6-am-(dont-touch)"
```

#### View Schedules

Triggers are a first-level citizen of the ZenML platform. You can view detailed information in the dashboard as well as via the SDK and CLI.

Via the dashboard:

To view schedules, you need to navigate to the `Triggers` tab:

![Image Showing Triggers tab](https://884225131-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoT4CiM88wQeSLTcwLU2J%2Fuploads%2Fgit-blob-be1ee8dcd7c4932d26b482866fa51c483df001e4%2Fschedule_list_dsb.png?alt=media)

You can inspect a schedule's information:

![Image Showing Schedule View](https://884225131-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoT4CiM88wQeSLTcwLU2J%2Fuploads%2Fgit-blob-39c591e612d36fd78f5855e1665bc5d1ee722a5d%2Fschedule_view_dsb.png?alt=media)

Or its attached snapshots and executed pipeline runs:

![Image Showing Schedule Snapshots](https://884225131-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoT4CiM88wQeSLTcwLU2J%2Fuploads%2Fgit-blob-6989ad5ef4c1f006f22688c267ccd384a88a111d%2Fschedule_snaps_dsb.png?alt=media)

![Image Showing Schedule Runs](https://884225131-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoT4CiM88wQeSLTcwLU2J%2Fuploads%2Fgit-blob-146f8b9ada8ed7c3328c1ab9ae8a64a19a5bc7a1%2Fschedule_runs_dash.png?alt=media)

Via the SDK:

```python
from zenml.client import Client

client = Client()

active_schedules = client.list_schedule_triggers(
    active=True,
)  # list schedules

schedule = client.get_schedule_trigger(trigger_id="<SCHEDULE_ID>")  # get a schedule by ID

for snapshot in schedule.snapshots:  # iterate a schedule's attached snapshots
    print(snapshot.id)
```

Via the CLI:

```bash
zenml trigger schedule list --active=true
```

#### Delete schedules

Triggers in ZenML are archivable objects. When a Trigger is archived (soft-deleted), it is deactivated and can no longer be used, but it remains in the system to preserve references for visibility and debugging.

Archiving (soft deletion) is the default deletion mode. Triggers can also be permanently deleted. Neither operation can be reversed.

Via the dashboard:

![Image Showing Schedule Deletion](https://884225131-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoT4CiM88wQeSLTcwLU2J%2Fuploads%2Fgit-blob-c3c4d6756cb7e9051242ed8b1c3cec46e02ffbc0%2Fdelete_schedule_soft.png?alt=media)

You can view archived schedules by setting the `Display archived` where can you also hard delete them.

![Image Showing Schedule Hard Deletion](https://884225131-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoT4CiM88wQeSLTcwLU2J%2Fuploads%2Fgit-blob-549243cffe4e5ce5583b5fbfb75164fdfdaaf446%2Fdelete_schedule_hard.png?alt=media)

Via the SDK:

```python
from zenml.client import Client

client = Client()

client.delete_trigger(
    trigger_id="<SCHEDULE_ID>",
    soft=True,  # set to False if you want to hard-delete the schedule.
)
```

Via the CLI:

```bash
zenml trigger schedule delete "<SCHEDULE_ID>" --soft=true  # set to False to hard-delete the schedule
```

### Triggers vs OSS schedules

ZenML provides [scheduling](https://github.com/zenml-io/zenml/blob/main/docs/book/how-to/steps-pipelines/scheduling.md) as an open-source feature. This section outlines the differences between open-source schedules and schedule-based Triggers, and explains why Triggers are better suited for production workloads:

* Lifecycle management
  * Triggers: You can update or delete a schedule at any time, and changes are automatically applied across the system.
  * OS Schedules: Updates and deletions must be managed manually on the orchestrator side (except when using the `KubernetesOrchestrator`).
* Feature support
  * Triggers: All scheduling features are consistently available across stacks.
  * OS Schedules: Feature availability depends on the scheduling capabilities of the selected orchestrator.
* Flexibility
  * Triggers: Snapshots and schedules are managed independently. You can dynamically attach or detach snapshots to or from schedules.
  * OS Schedules: Schedules are bound to individual pipelines and cannot be shared across multiple pipelines.
* Visibility
  * Triggers: Extended dashboard visibility and management.
  * OS Schedules: Limited dashboard exposure.

<figure><img src="https://static.scarf.sh/a.png?x-pxid=f0b4f458-0a54-4fcd-aa95-d5ee424815bc" alt="ZenML Scarf"><figcaption></figcaption></figure>
