Database Change trigger
The workhorse trigger: run a workflow when a CRM record is created, updated or deleted. Watching the right fields, and the self-trigger loop that catches everyone once.
Most automation starts with something changing in the CRM. A contact is created. A deal moves to Won. A task gets an owner. The Database Change Trigger is how a workflow hears about it.
It is the most-used trigger in the product, and the one worth understanding properly — the other nine are easier once this one is clear.
A worked example
A contact is created; a task appears
Click the trigger to see what it watches.
| Field | What it holds |
|---|---|
target_table | Database table to monitor One of: contacts · companies · deals · tasks · notes · deal_payments · voice_calls Defaults to contacts. |
operations | Database operations to monitor |
watched_fields | Only trigger on UPDATE if at least one of these fields actually changed. Leave empty to trigger on any field change. Does not affect INSERT/DELETE. |
ignored_fields | Do NOT trigger on UPDATE when ONLY these fields changed. List the fields THIS workflow writes (e.g. 'lifecycle_stage_id_fk', 'custom_fields') so it can't re-fire on its own writes — prevents self-trigger loops. Use the whole column name for JSON columns. Does not affect INSERT/DELETE. |
filter_config | Optional filters to apply |
target_table
- What it holds
- Database table to monitor One of:
contacts · companies · deals · tasks · notes · deal_payments · voice_callsDefaults tocontacts.
operations
- What it holds
- Database operations to monitor
watched_fields
- What it holds
- Only trigger on UPDATE if at least one of these fields actually changed. Leave empty to trigger on any field change. Does not affect INSERT/DELETE.
ignored_fields
- What it holds
- Do NOT trigger on UPDATE when ONLY these fields changed. List the fields THIS workflow writes (e.g. 'lifecycle_stage_id_fk', 'custom_fields') so it can't re-fire on its own writes — prevents self-trigger loops. Use the whole column name for JSON columns. Does not affect INSERT/DELETE.
filter_config
- What it holds
- Optional filters to apply
Watch out: operations are UPPERCASE: ["INSERT", "UPDATE"]. target_table is an enum (contacts/companies/deals/…).
Read the changed row as {{alias.new_data.<column>}} (NOT {{alias.<column>}}).
Reading the record that changed
The trigger hands the whole row to the workflow, and the shape catches people out: it is {{alias.new_data.<column>}}, not {{alias.<column>}}. Alongside it you get:
| Field | Holds |
|---|---|
new_data | The row as it is now. What you want most of the time. |
old_data | The row as it was. Only meaningful on an update. |
changed_fields | What actually changed, with old and new values. |
entity_id | The record's id — the same as new_data.id, and shorter to type. |
new_data
- Holds
- The row as it is now. What you want most of the time.
old_data
- Holds
- The row as it was. Only meaningful on an update.
changed_fields
- Holds
- What actually changed, with old and new values.
entity_id
- Holds
- The record's id — the same as
new_data.id, and shorter to type.
Having both old_data and new_data is what lets a workflow ask “did this deal just become Won?” rather than “is this deal Won?” — a distinction that matters, because the second one is true on every subsequent edit too.
Watched fields, and why the default is too broad
Leave watched_fields empty and the trigger fires on any update to the table. A contact's phone number, a typo fixed in a name, a system field touched by another workflow — all of it starts your run.
Naming the fields you care about is the single highest-value setting on this node. A workflow that should react to lifecycle changes should say watched_fields: [lead_status] and nothing else.
The self-trigger loop
The failure everyone hits once. A workflow triggered by a change to contacts, which then updates a contact, has just triggered itself. It runs again, updates again, and keeps going. ignored_fields exists to stop exactly this: list the fields your own workflow writes, and a change to only those will not fire it.
The example above ignores last_contacted_at and updated_at for that reason — they are fields automation touches constantly, and reacting to them is almost never what anyone means.
- Watched fields say “only start when these change”.
- Ignored fields say “never start when only these change”.
Use watched fields when you know what you care about. Use ignored fields when you cannot list everything, but you know what your own automation writes.
Insert, update, delete
operations takes a list, and the values are uppercase — ["INSERT", "UPDATE"]. Choosing more than one is common and worth thinking about: an INSERT has no old_data, so a workflow handling both needs to cope with that field being empty.
Try it
- Add a Database Change Trigger on
contactswithoperations: ["UPDATE"]and no watched fields. - Have it create a note, then edit a contact's phone number and watch it fire for a change you did not care about.
- Now set
watched_fieldsto one field, edit the phone again, and confirm it stays quiet. - Finally, print
{{alias.changed_fields}}into the note and edit that watched field — the log shows you exactly what the trigger saw.
Next: the Segment Trigger — the same idea, but the thing that changed is which group a contact belongs to.
Related lessons
Base rates — what a piece of evidence is actually worth
A face-recognition system that is 99.9% accurate and almost entirely wrong, and a number that sent an innocent woman to prison. Both are the same arithmetic, and it is the arithmetic that decides what any piece of evidence is worth.
ReadConfirmation and survivorship — what you never looked for
Two questions about evidence you did not go looking for. One is a rule you have to discover, and one is a pattern in five famous people — and in both, the thing that would have told you the truth is the thing nobody checks.
ReadLoss aversion, sunk cost and regression — what it costs you
Four questions you answer about yourself rather than about a scenario, and your own answers are the finding. Then the pattern that makes praise look useless and criticism look like it works, whatever you actually do.
Read
