How Triggers Work
A trigger consists of two parts:- Trigger Function: A function that contains the code to execute
- Trigger Definition: Specifies when and how to call the function
Trigger Timing
Triggers can fire at different times relative to the triggering event.BEFORE Triggers
Execute before the operation. Can modify the data being inserted/updated.AFTER Triggers
Execute after the operation completes. Cannot modify the data.Trigger Events
Triggers can respond to different types of operations.INSERT Trigger
UPDATE Trigger
DELETE Trigger
Multiple Events
Trigger Variables
Trigger functions have access to special variables:NEW: The new row data (INSERT/UPDATE)OLD: The old row data (UPDATE/DELETE)TG_OP: The operation type (‘INSERT’, ‘UPDATE’, ‘DELETE’, ‘TRUNCATE’)TG_TABLE_NAME: The name of the table that fired the triggerTG_TABLE_SCHEMA: The schema of the tableTG_WHEN: ‘BEFORE’ or ‘AFTER’TG_LEVEL: ‘ROW’ or ‘STATEMENT’
Real Example: Salary History Tracking
Here’s a complete example of tracking employee salary changes:Real Example: Auto-updating Timestamps
Real example from Supabase source code:Real Example: Soft Delete with Rule
Another pattern from Supabase source:Row Level vs Statement Level
FOR EACH ROW
Executes once per affected row (most common):FOR EACH STATEMENT
Executes once per SQL statement, regardless of rows affected:Conditional Triggers
Use WHEN clause to conditionally execute triggers:Realtime Integration
Supabase triggers can publish real-time events. Here’s an example from the Slack clone:Advanced: Auth Hook Trigger
Real example from Slack clone - automatically create user profile:Managing Triggers
Disable/Enable Trigger
Drop Trigger
List Triggers
Common Use Cases
Audit Logging
Audit Logging
Track all changes to sensitive tables for compliance and debugging.
Data Validation
Data Validation
Enforce complex business rules that can’t be expressed with simple constraints.
Derived Data
Derived Data
Automatically update calculated fields or summary tables.
Cascading Changes
Cascading Changes
Update related records when a parent record changes.
Notifications
Notifications
Send alerts or trigger workflows when important events occur.
Best Practices
Keep triggers simple
Keep triggers simple
Complex logic should be in the application or database functions, not triggers.
Avoid trigger chains
Avoid trigger chains
Don’t create triggers that fire other triggers (can lead to infinite loops).
Use WHEN clause
Use WHEN clause
Filter trigger execution to only when necessary.
Consider statement-level triggers
Consider statement-level triggers
For bulk operations, statement-level triggers are more efficient.
Set search_path on security definer
Set search_path on security definer
Always set
search_path on security definer trigger functions.Troubleshooting
Infinite Trigger Loops
Debugging Triggers
Next Steps
Functions
Learn more about database functions
Tables
Understand table structures and relationships
Extensions
Explore PostgreSQL extensions
Realtime
Subscribe to database changes in real-time
