Skip to main content

Filters & Transforms

Filters and transforms sit between the source and target in each pipeline. The engine applies the chain before dispatching to the target.

Filters

A filter returns true to include a row, false to skip it. Applied to both baseline rows and change events.

Built-in filters

TypeConfig nameDescription
FieldEqualsfield-equalsMatch rows where a field equals a value
FieldPrefixfield-prefixMatch rows where a string field starts with a prefix
FieldRegexfield-regexMatch rows where a field matches a regex

Configuration

filters = [
{ type = field-equals, field = status, value = active }
{ type = field-prefix, field = key, prefix = "rulesets/" }
]

Custom filters (library)

laredo.PipelineFilterOpt(laredo.PipelineFilterFunc(
func(table laredo.TableIdentifier, row laredo.Row) bool {
return row.GetString("status") == "active"
},
))

Transforms

A transform modifies a row before it reaches the target. Return nil to drop the row entirely.

Built-in transforms

TypeConfig nameDescription
DropFieldsdrop-fieldsRemove specified fields from the row
RenameFieldsrename-fieldsRename fields
AddTimestampadd-timestampAdd a field with the current timestamp

Configuration

transforms = [
{ type = drop-fields, fields = [ssn, internal_notes] }
{ type = rename-fields, mapping = { old_name = new_name } }
{ type = add-timestamp, field = synced_at }
]

Custom transforms (library)

laredo.PipelineTransformOpt(laredo.PipelineTransformFunc(
func(table laredo.TableIdentifier, row laredo.Row) laredo.Row {
return row.Without("ssn", "internal_notes")
},
))

Chain ordering

Filters and transforms are applied in order. Filters run first (skip rows early), then transforms modify the surviving rows.

Publication-level vs. pipeline-level

PostgreSQL 15+ supports row filters and column lists at the publication level, which reduces WAL volume at the source. Pipeline filters are independent and handle any additional per-target filtering. Use both when appropriate.