Tom Wiedenbein
12/12/2025, 4:38 PMMarvin
12/12/2025, 4:38 PMMarvin
12/12/2025, 4:41 PMmatch to scope to flow runs, then use match_related with multiple entries (AND logic) to require both the flow and the tag.
Example (custom JSON trigger):
{
"type": "metric",
"match": {
"prefect.resource.id": "prefect.flow-run.*"
},
"match_related": [
{
"prefect.resource.id": "prefect.flow.<flow-id>",
"prefect.resource.role": "flow"
},
{
"prefect.resource.id": "prefect.tag.production",
"prefect.resource.role": "tag"
}
],
"metric": {
"name": "successes",
"operator": "<",
"threshold": 0.9,
"range": 3600,
"firing_for": 300
}
}
Notes:
- You can also target the flow by name (wildcards supported) using prefect.resource.name instead of the flow id.
- In the UI, if the basic controls don’t expose this, switch to “Custom trigger (JSON)”.
- Metric triggers are available in Prefect Cloud.
Docs:
- Event and metric triggers (filters)
- Creating automations
- Automation schema APITom Wiedenbein
12/15/2025, 11:05 PMMarvin
12/15/2025, 11:05 PMMarvin
12/15/2025, 11:10 PMfiring_for duration (lookback defined by range). If your Compound trigger has require: "all" but within is shorter than the child firing_for, they’ll never be simultaneously “firing.”
- Fix: set within ≥ the largest firing_for (and practically a bit larger than both children’s firing_for values).
- Different match filters
- If the two metric triggers use different match scopes (e.g., different resources), they may never fire together. Ensure the same match filter or that they can realistically co-occur.
- Very tight thresholds/lookbacks
- If the thresholds are rarely met or the `range`/`firing_for` windows are too strict, you may not see them overlap.
If you’re using Compound triggers in Cloud, a working pattern looks like this (note the long enough within and identical match filters):
{
"name": "Alert when two metrics are breached",
"trigger": {
"type": "compound",
"require": "all", // "all" = AND, "any" = OR
"within": 1200, // should be >= the largest firing_for below
"triggers": [
{
"type": "metric",
"match": {"prefect.resource.id": "prefect.flow-run.*"},
"metric": {
"name": "<metric-name-1>",
"operator": ">",
"threshold": <value>,
"range": 900,
"firing_for": 600
}
},
{
"type": "metric",
"match": {"prefect.resource.id": "prefect.flow-run.*"},
"metric": {
"name": "<metric-name-2>",
"operator": ">",
"threshold": <value>,
"range": 900,
"firing_for": 600
}
}
]
},
"actions": [
{ "type": "notify", "block_document_id": "<your-notification-block-id>" }
]
}
Can you share:
- Whether you’re on Prefect Cloud or OSS
- The JSON for your automation (from the Cloud UI) or a snippet of how you constructed it
- The values you used for range, firing_for, and (if present) the parent Compound trigger’s within
- The match filters for each metric trigger
With that, I can pinpoint why it didn’t fire and suggest an exact change.
References:
- Automations concepts
- Event and composite triggers (AND/OR/within)Tom Wiedenbein
12/15/2025, 11:17 PM{
"type": "metric",
"match": {
"prefect.resource.id": "prefect.flow-run.*"
},
"match_related": [
{
"prefect.resource.id": "prefect.flow.<flow-id>",
"prefect.resource.role": "flow"
},
{
"prefect.resource.id": "prefect.tag.production",
"prefect.resource.role": "tag"
}
],
"metric": {
"name": "successes",
"operator": "<",
"threshold": 0.9,
"range": 3600,
"firing_for": 300
}
}
does not work. I put the correct flow ID in there as specified, made sure the tag was right, and no alert triggers.Marvin
12/15/2025, 11:17 PMMarvin
12/15/2025, 11:21 PMsuccesses is a count of successful flow runs in the lookback window (range), not a success rate.
- With operator: "<" and threshold: 0.9, you’re effectively asking “is the number of successes in the last hour less than 1?” That only fires when there are zero successes — and only if that condition stays true for the entire firing_for window (5 minutes).
So if even one run succeeds in the last hour, the condition is false and won’t fire.
What to change (if your intent was “success rate below 90%”):
- Prefect metric automations don’t currently support a success rate metric — just lateness, duration, and successes (count).
- If you want to alert on “few successes,” pick an integer threshold that matches your volume, e.g. “fewer than 3 successes in the last hour”:
"metric": {
"name": "successes",
"operator": "<",
"threshold": 3,
"range": 3600,
"firing_for": 300
}
- If you truly want “zero successes in the last hour,” make the intent explicit and use `< 1`:
"metric": {
"name": "successes",
"operator": "<",
"threshold": 1,
"range": 3600,
"firing_for": 300
}
A few other checks that commonly block firing:
- firing_for vs. data: The condition must remain true continuously for 300s. If a success happens at any point, “successes in last hour” becomes ≥ 1 for the next hour and the condition won’t be true for 5 straight minutes.
- Filters: Your match_related includes both a specific flow and the production tag. In Cloud, a list in match_related means the run must be related to each of those resources. Make sure:
- The flow run is related to the flow resource prefect.flow.<flow-id> you specified.
- The run actually carries the tag resource prefect.tag.production (as a related resource), not just a label you expect. An easy test is to temporarily remove the tag filter and see if the trigger can fire.
- Primary match is fine: match: {"prefect.resource.id": "prefect.flow-run.*"} is standard.
Quick debug steps:
1. Temporarily simplify to just the flow filter (remove the tag):
"match_related": [
{"prefect.resource.id": "prefect.flow.<flow-id>", "prefect.resource.role": "flow"}
]
2. Use a threshold that will clearly become true/false in your environment, e.g. < 1 or < 2.
3. After you confirm it fires, add the tag filter back. If it stops firing, the tag relationship is the culprit.
4. Ensure your flow/run frequency and `range`/`firing_for` align with how often you get successes.
If your goal is truly “success rate < 90%,” that’s not directly expressible with metric automations today. A common workaround is to:
- Choose a count threshold (e.g., “< 3 successes in 1 hour”) that approximates your expected rate given run volume, and
- Pair it with a reactive event trigger for failures to get earlier signals on problem runs.
Docs for reference:
- Automations concepts
- Event and composite triggers
If you can share:
- The intended condition (rate vs. count),
- Typical runs/hour for that flow,
- Whether removing the tag filter makes it fire,
I can give you an exact configuration that will behave as you expect.