When setting up a sink, you can optionally specify one or more filters to apply to the table:

Only changes and rows that match the filters will be sent to the sink.

Operations to capture

When using change messages, you can specify which Postgres operations to capture:

  • insert
  • update
  • delete

If you backfill a table to a sink, Sequin will send read messages for each row in the table, regardless of which operations you specify.

You do not specify Postgres operations for row messages. Instead, Sequin will always capture the latest version of each row.

Column filters

Column filters are SQL expressions (i.e. where clauses) that Sequin will use to filter the rows that are sent to the sink.

  • Column: The column to filter on.
  • Operator: The operator to use for the filter.
  • Comparison value: The comparison value to use for the filter.

The available operators are:

  • =
  • !=
  • >
  • >=
  • <
  • <=
  • in
  • not in
  • is null
  • is not null

JSON filters

Sequin also supports filtering on JSON columns. When you select a JSON column as the Column to filter on, you’ll see an expanded set of input fields:

  • Column: The selected JSONB column to filter on.
  • Field path: The path to the JSONB field you want to filter on. Use dot notation for nested fields (e.g., “address.city”).
  • Field type: The data type of the JSONB field you’re filtering on. This helps ensure proper comparison and filtering.
  • Operator: The operator to use for the filter.
  • Comparison value: The comparison value to use for the filter.

Filter functions

Filter functions provide more advanced filtering capabilities than what’s possible with column filters alone. They allow you to:

  • Apply complex conditional logic to your data
  • Compare new and old values for changed rows
  • Use string pattern matching or regular expressions
  • Implement custom business logic for filtering

Filter functions are written in Elixir and must return a boolean value (true or false). Filter functions that return non-boolean values will fail to execute.

How filter functions work

When you create a filter function, you define an Elixir function that evaluates whether a message should be processed. For each message, your filter function receives:

def filter(action, record, changes, metadata) do
  # Your filtering logic here
  # Must return true or false
end

Parameters:

  • action: The operation type (e.g., “insert”, “update”, “delete”)
  • record: The full row/record data as a map with string keys
  • changes: For update operations, contains the old values that were changed
  • metadata: Additional information like table name, timestamp, etc.

How filters are combined

When you set up a sink with multiple types of filters, all filters are applied with a logical AND. This means:

  1. The operation must match one of the selected operations (insert, update, delete)
  2. The data must pass all column filters (if any)
  3. The filter function (if specified) must return true

If any of these conditions fail, the message will not be delivered to the sink.

Example filter functions

Filter by string pattern

def filter(action, record, changes, metadata) do
  # Only process records where name starts with "A"
  String.starts_with?(record["name"], "A")
end

Filter by multiple conditions

def filter(action, record, changes, metadata) do
  # Only process VIP customers with high-value orders
  record["customer_type"] == "VIP" and record["is_deleted"] == false
end

Complex filtering with metadata

def filter(action, record, changes, metadata) do
  # Filter based on both record content and metadata
  is_high_priority = record["priority"] == "high"
  is_users_table = metadata.table_name == "users"
  
  # Only process high priority records from the users table
  is_high_priority and is_users_table
end

Filtering based on changes

def filter(action, record, changes, metadata) do
  # Only process updates where the status changed from "pending" to "approved"
  action == "update" and 
    changes["status"] == "pending" and 
    record["status"] == "approved"
end

Testing filter functions

When creating or editing a filter function, Sequin will automatically capture recent events from your database so you can test your function with real data. You’ll see a live preview showing which messages would pass or fail your filter.