Database Watches
Watches are event-driven triggers. Instead of running on a fixed schedule, DataRunner polls your database at a configurable interval and fires the moment new rows match your SQL condition — no scheduled times, no delays.
- Read
- 7 min
- Sections
- 7
- Min interval
- 60 s
How watches work
A watch has three parts:
- Trigger query — a SQL SELECT that returns rows when your condition is met
- Poll interval — how often DataRunner runs the trigger query (minimum 60 seconds)
- Action — what DataRunner does when new rows are found
On every poll, DataRunner runs the trigger query and compares the results to the previous poll. If new rows appeared since the last poll, the watch fires its configured action. Rows that already triggered the watch will not trigger it again — DataRunner tracks which rows have fired using a unique identifier column you specify.
Creating a watch
Go to Watches → New watch. Configure:
- Name — a descriptive label for this watch
- Connection — which database to poll
- Trigger query — SQL that returns the rows you want to watch for
- Unique ID column — a column (usually a primary key or UUID) that uniquely identifies each row, used for deduplication
- Poll interval — how often to check, in seconds (minimum 60)
- Action — what to do when new rows are found
Trigger conditions
The trigger query can be any SELECT statement. DataRunner fires whenever this query returns rows that weren't returned in the previous poll. There are no restrictions on query complexity — you can use joins, CTEs, subqueries, and window functions.
SELECT id, customer_id, total, created_at FROM orders WHERE created_at > NOW() - INTERVAL '5 minutes'
SELECT id, user_id, amount, error_code, attempted_at FROM payment_attempts WHERE status = 'failed' AND attempted_at > NOW() - INTERVAL '1 hour'
SELECT sku, product_name, stock_qty FROM inventory WHERE stock_qty < 10 AND active = true
SELECT id, job_type, error_message, failed_at FROM background_jobs WHERE status = 'failed' AND failed_at > NOW() - INTERVAL '2 minutes'
created_at > NOW() - INTERVAL '5 minutes') to keep queries fast and avoid scanning the full table on every poll.Watch actions
When a watch fires, it can perform one or more of the following actions:
Email alert
Send an email to configured recipients. The email body can include the number of new rows matched and a summary of the trigger data. Configure in Settings → Email first.
Slack notification
Post a message to a Slack channel or DM. Include a row count summary and trigger details in the message body. Requires a Slack integration in Settings → Channels.
Webhook
POST a JSON payload to an HTTP endpoint. The payload includes the watch name, trigger timestamp, matched row count, and the full result rows as a JSON array. Useful for integration with PagerDuty, OpsGenie, Zapier, or custom backends.
{
"watch_id": "wt_01hxyz",
"watch_name": "Failed payments",
"triggered_at": "2026-05-28T14:23:01Z",
"matched_rows": 3,
"rows": [
{ "id": 4821, "user_id": 99, "amount": 49.00, "error_code": "card_declined" },
...
]
}Full report delivery
Instead of just an alert, deliver the complete result set as a formatted report (CSV, Excel, or PDF) to any configured channel. This is the same delivery mechanism as scheduled reports — the difference is the trigger is event-driven rather than time-based.
Poll interval and performance
The minimum poll interval is 60 seconds. For most use cases, 5—15 minutes is a good starting point. Shorter intervals mean more frequent queries — balance responsiveness with database load.
EXPLAIN ANALYZE in the workbench to verify query performance before setting a short poll interval.Deduplication
DataRunner uses the Unique ID column you configure to track which rows have already fired. A row that matched the trigger on a previous poll will not trigger the action again — even if it continues to appear in the trigger query results.
This means your trigger query does not need to track "already-seen" rows itself — DataRunner handles deduplication. You can write a simple recency-based query and DataRunner ensures each row triggers the action exactly once.
Watch history
The History tab on each watch shows every trigger event: timestamp, matched row count, and delivery confirmation per action. You can drill into any event to see the full result set that matched.