---
title: "Job Filters: Run on the Events That Matter"
url: https://www.insulin.dev/blog/which-events-actually-run-a-job/
canonical: https://www.insulin.dev/blog/which-events-actually-run-a-job/
type: Blog
description: "Filter expressions decide which events trigger an agent run, skipped runs are recorded as Filtered, and a job with no filter fires on everything."
---

# Job Filters: Run on the Events That Matter

> Canonical HTML version: https://www.insulin.dev/blog/which-events-actually-run-a-job/

1.  [Home](/)
2.  /
3.  [Blog](/blog/)
4.  /
5.  Which Events Actually Run a Job, and Which Get Filtered

# Which Events Actually Run a Job, and Which Get Filtered

A job with no filter runs on every event it receives. A filter expression is what turns a firehose into an automation, and skipped runs are recorded rather than lost.

![Shirley Guo](/authors/shirley-guo.jpg)

Shirley Guo

Sep 13, 2026

 ![Which Events Actually Run a Job, and Which Get Filtered](/images/blog/which-events-actually-run-a-job/hero.png)

Explore AI Summary

 [![](/logos/company/openai.svg)](https://chat.openai.com/?q=Read%20and%20summarize%20https%3A%2F%2Fwww.insulin.dev%2Fblog%2Fwhich-events-actually-run-a-job%2F%2C%20then%20cite%20the%20source.%20Focus%20on%20what%20it%20says%20about%20Jobs. "Summarize with ChatGPT")[![](/logos/company/anthropic.svg) ](https://claude.ai/new?q=Read%20and%20summarize%20https%3A%2F%2Fwww.insulin.dev%2Fblog%2Fwhich-events-actually-run-a-job%2F%2C%20then%20cite%20the%20source.%20Focus%20on%20what%20it%20says%20about%20Jobs. "Summarize with Claude")[![](/logos/company/gemini.svg)](https://www.google.com/search?udm=50&aep=11&q=Read%20and%20summarize%20https%3A%2F%2Fwww.insulin.dev%2Fblog%2Fwhich-events-actually-run-a-job%2F%2C%20then%20cite%20the%20source.%20Focus%20on%20what%20it%20says%20about%20Jobs. "Summarize with Gemini")[](https://www.perplexity.ai/search/new?q=Read%20and%20summarize%20https%3A%2F%2Fwww.insulin.dev%2Fblog%2Fwhich-events-actually-run-a-job%2F%2C%20then%20cite%20the%20source.%20Focus%20on%20what%20it%20says%20about%20Jobs. "Summarize with Perplexity")

Table of Contents

-   [What a filter is evaluated against](#what-a-filter-is-evaluated-against)
-   [The syntax](#the-syntax)
-   [How to write one that keeps working](#how-to-write-one-that-keeps-working)
-   [Frequently asked questions](#frequently-asked-questions)
-   [Takeaways](#takeaways)

_The default is not “runs on nothing.” The default is “runs on everything.”_

* * *

An event-triggered job is subscribed to a stream, and streams are busier than they look. **If no filter expression is set, every event passes and triggers an agent run** — which is the correct default for a job you are still designing and the wrong one for a job you have left running.

## What a filter is evaluated against

When an event arrives on a push job — or a cron tick fires carrying a payload — the filter is evaluated against that payload. Return false and the run is **skipped and recorded with the `Filtered` status**.

That recording matters more than it sounds. A filtered run is not a silent non-event: it is a visible statement that the job saw something and declined it. When a job is not doing what you expected, the first question is which of the two it is — no events arriving, or events arriving and being filtered out — and the status answers it without guessing.

## The syntax

Filters use **filtrex**, a safe sandboxed expression language, with the payload under the `event` namespace:

```
event.source == "aws-marketplace"
```

```
event.amount > 1000
```

```
event.action == "entitlement_created" and event.partner == "AWS"
```

```
lower(event.status) == "active"
```

**Available functions:** `lower()`, `upper()`, and `includes()` for checking whether an array contains a value. **Dot notation** reaches nested fields — `event.buyer.name`, `event.offer.info.commits`.

`lower()` is the one to reach for by habit. Comparing a status field exactly is a filter that works until the day a system sends `Active` instead of `active`, and that day arrives without an announcement.

## How to write one that keeps working

**Filter on the field that means what you want, not the field that happens to correlate with it.** `event.amount > 1000` and `event.action == "entitlement_created"` are both narrow, but only one of them will still mean the same thing after somebody changes your pricing.

**Start permissive, then tighten.** Run the job with no filter, look at what actually arrives, then write the expression against real payloads. Writing the filter from the shape you _expect_ is how you end up with a job that has been silently filtering everything for a week.

**Check the `Filtered` count after you deploy one.** A job that suddenly stopped producing runs and a job that is correctly declining irrelevant events look identical from a distance and completely different in the status column.

## Frequently asked questions

### What happens if a job has no filter expression?

Every event passes and triggers an agent run. The default is permissive, which suits a job you are still designing and not one left running.

### What does the Filtered status mean?

The event arrived, the filter evaluated to false, and the run was skipped — recorded rather than discarded, so you can tell “no events” from “events declined.”

### What syntax do filter expressions use?

Filtrex, a safe sandboxed expression language, with the event payload under the `event` namespace. `lower()`, `upper()` and `includes()` are available, and dot notation reaches nested fields.

### How do I compare a status field safely?

Wrap it in `lower()`. An exact comparison works until an upstream system sends a differently-cased value, which happens without warning.

### Why is my job not running?

Check whether events are arriving at all, then whether they are being recorded as Filtered. The two look the same from outside and have opposite fixes.

## Takeaways

-   **No filter means every event runs the job** — the default is permissive.
-   A skipped run is recorded as `Filtered`, which is how you tell silence from rejection.
-   Filtrex syntax, `event` namespace, `lower()` / `upper()` / `includes()`, dot notation for nested fields.
-   Use `lower()` on anything case-sensitive by habit.
-   Write the filter against payloads you have actually seen, not the ones you expect.

More on triggers and scheduling in [jobs](/jobs/).

## Sources

Primary sources for the platform rules cited above. Last verified September 13, 2026. Cloud providers change fees, eligibility, and program terms without notice — check the source before relying on a figure.

-   [Suger docs: Jobs — Filter Expressions](https://doc.suger.io/insulin/jobs/) — Filtrex syntax, the event namespace, available functions, and the Filtered run status

## Keep reading

-   [JobsScheduled AI Job Not Running? Where to Look FirstSep 19, 2026](/blog/why-a-scheduled-ai-job-did-not-run/)
-   [JobsHow to Build an AI Executive-Briefing AgentAug 24, 2026](/blog/ai-executive-briefing-agent/)
-   [JobsAI Agent Failure Handling: Retries to RollbacksAug 20, 2026](/blog/ai-agent-failure-handling/)
-   [AutomationAI Agent Observability: What Business and IT Teams Should MonitorAug 20, 2026](/blog/ai-agent-observability/)

[Browse every post on the Insulin Blog](/blog/)

### Stay Updated

Get the latest Cloud GTM insights, product updates, and marketplace strategies delivered to your inbox.
