Trigger
Trigger allows you to define evaluation rules with SQL. GreptimeDB evaluates these rules periodically; once the condition is met, a notification is sent out.
Key Features
- SQL-native: Define trigger rules in SQL, reusing GreptimeDB's built-in functions without a learning curve
- Multi-stage state management: Built-in pending / firing / inactive state machine prevents flapping and duplicate notifications
- Rich context: Custom labels and annotations with automatic injection of query result fields to pinpoint root causes
- Ecosystem-friendly: Alert payload fully compatible with Prometheus Alertmanager—use its grouping, inhibition, silencing, and routing without adapters
Quick Start Example
This section walks through an end-to-end alerting scenario: monitor system load
(load1) and fire alerts when load exceeds a threshold.
In this quick start, you will:
- Create a
load1table to store host load metrics - Define a Trigger with conditions, labels, annotations, and notifications
- Simulate data ingestion with normal and abnormal values
- Watch alerts transition through pending → firing → inactive
1. Create the Data Table
Connect to GreptimeDB with a MySQL client and create the load1 table:
CREATE TABLE `load1` (
host STRING,
load1 FLOAT32,
ts TIMESTAMP TIME INDEX
) WITH ('append_mode'='true');
2. Create Trigger
Connect to GreptimeDB with MySQL client and create the load1_monitor trigger:
CREATE TRIGGER IF NOT EXISTS `load1_monitor`
ON (
SELECT
host AS label_host,
avg(load1) AS avg_load1,
max(ts) AS ts
FROM public.load1
WHERE ts >= NOW() - '1 minutes'::INTERVAL
GROUP BY host
HAVING avg(load1) > 10
) EVERY '1 minutes'::INTERVAL
FOR '3 minutes'::INTERVAL
KEEP FIRING FOR '3 minutes'::INTERVAL
LABELS (severity=warning)
ANNOTATIONS (comment='Your computer is smoking, should take a break.')
NOTIFY(
WEBHOOK alert_manager URL 'http://localhost:9093' WITH (timeout='1m')
);
This Trigger runs every minute, computes average load per host over the last
60 seconds, and produces an alert instance for each host where avg(load1) > 10.
Key parameters:
- FOR: Specifies how long the condition must continuously hold before an alert instance enters firing state.
- KEEP FIRING FOR: Specifies how long an alert instance stays in the firing state after the condition no longer holds.
See the trigger syntax for more detail.
3. Check Trigger Status
List all Triggers
SHOW TRIGGERS;
Output:
+---------------+
| Triggers |
+---------------+
| load1_monitor |
+---------------+
View the creation statement
SHOW CREATE TRIGGER `load1_monitor`\G
Output:
*************************** 1. row ***************************
Trigger: load1_monitor
Create Trigger: CREATE TRIGGER IF NOT EXISTS `load1_monitor`
ON (SELECT host AS label_host, avg(load1) AS avg_load1 ...) EVERY '1 minutes'::INTERVAL
FOR '3 minutes'::INTERVAL
KEEP FIRING FOR '3 minutes'::INTERVAL
LABELS (severity = 'warning')
ANNOTATIONS (comment = 'Your computer is smoking, should take a break.')
NOTIFY(
WEBHOOK `alert_manager` URL `http://localhost:9093` WITH (timeout = '1m'),
)
View Trigger details
SELECT * FROM information_schema.triggers\G
Output:
*************************** 1. row ***************************
trigger_name: load1_monitor
trigger_id: 1024
raw_sql: (SELECT host AS label_host, avg(load1) AS avg_load1, ...)
interval: 60
labels: {"severity":"warning"}
annotations: {"comment":"Your computer is smoking, should take a break."}
for: 180
keep_firing_for: 180
channels: [{"channel_type":{"Webhook":{"opts":{"timeout":"1m"}, ...}]
flownode_id: 0
See the Triggers for more details.
View alert instances
SELECT * FROM information_schema.alerts;
With no data written yet, this returns an empty set.
See the Alerts for more details.
4. Write Data and Observe Alert States
This script simulates data ingestion: normal values for the first minute, high values for 6 minutes to trigger alerts, then back to normal.
#!/usr/bin/env bash
MYSQL="mysql -h 127.0.0.1 -P 4002"
insert_normal() {
$MYSQL -e "INSERT INTO load1 (host, load1, ts) VALUES
('newyork1', 1.2, now()),
('newyork2', 1.1, now()),
('newyork3', 1.3, now());"
}
insert_high() {
$MYSQL -e "INSERT INTO load1 (host, load1, ts) VALUES
('newyork1', 1.2, now()),
('newyork2', 12.1, now()),
('newyork3', 11.5, now());"
}
# First minute: normal data
for i in {1..4}; do insert_normal; sleep 15; done
# Next 6 minutes: high values
for i in {1..24}; do insert_high; sleep 15; done
# After: back to normal
while true; do insert_normal; sleep 15; done
State Transitions
In another terminal, query alert status:
Phase 1: No alerts
SELECT * FROM information_schema.alerts\G
Output:
Empty set
Phase 2: pending (condition met, FOR duration not reached)
SELECT trigger_id, labels, active_at, fired_at, resolved_at FROM information_schema.alerts;
+------------+-----------------------------------------------------------------------+----------------------------+----------+-------------+
| trigger_id | labels | active_at | fired_at | resolved_at |
+------------+-----------------------------------------------------------------------+----------------------------+----------+-------------+
| 1024 | {"alert_name":"load1_monitor","host":"newyork3","severity":"warning"} | 2025-12-29 11:58:20.992670 | NULL | NULL |
| 1024 | {"alert_name":"load1_monitor","host":"newyork2","severity":"warning"} | 2025-12-29 11:58:20.992670 | NULL | NULL |
+------------+-----------------------------------------------------------------------+----------------------------+----------+-------------+
Phase 3: firing (FOR satisfied, notifications sent)
SELECT trigger_id, labels, active_at, fired_at, resolved_at FROM information_schema.alerts;
+------------+-----------------------------------------------------------------------+----------------------------+----------------------------+-------------+
| trigger_id | labels | active_at | fired_at | resolved_at |
+------------+-----------------------------------------------------------------------+----------------------------+----------------------------+-------------+
| 1024 | {"alert_name":"load1_monitor","host":"newyork3","severity":"warning"} | 2025-12-29 11:58:20.992670 | 2025-12-29 12:02:20.991713 | NULL |
| 1024 | {"alert_name":"load1_monitor","host":"newyork2","severity":"warning"} | 2025-12-29 11:58:20.992670 | 2025-12-29 12:02:20.991713 | NULL |
+------------+-----------------------------------------------------------------------+----------------------------+----------------------------+-------------+
Phase 4: inactive (condition cleared + KEEP FIRING FOR expired)
SELECT trigger_id, labels, active_at, fired_at, resolved_at FROM information_schema.alerts;
+------------+-----------------------------------------------------------------------+----------------------------+----------------------------+----------------------------+
| trigger_id | labels | active_at | fired_at | resolved_at |
+------------+-----------------------------------------------------------------------+----------------------------+----------------------------+----------------------------+
| 1024 | {"alert_name":"load1_monitor","host":"newyork3","severity":"warning"} | 2025-12-29 11:58:20.992670 | 2025-12-29 12:02:20.991713 | 2025-12-29 12:05:20.991750 |
| 1024 | {"alert_name":"load1_monitor","host":"newyork2","severity":"warning"} | 2025-12-29 11:58:20.992670 | 2025-12-29 12:02:20.991713 | 2025-12-29 12:05:20.991750 |
+------------+-----------------------------------------------------------------------+----------------------------+----------------------------+----------------------------+
5. Alertmanager Integration (Optional)
If you have Prometheus Alertmanager deployed, GreptimeDB automatically pushes firing and inactive alerts to it.
After each evaluation, the Trigger injects fields from the query results into
labels and annotations. In this example, host is included as a label and
avg_load1 is included as an annotation. These fields are propagated to
Alertmanager and can be referenced in notification templates.
Since the payload is Alertmanager-compatible, you can use grouping, inhibition, silencing, and routing without adapters.
Reference
- Trigger Syntax: The syntax for SQL statements
related to
TRIGGER - INFORMATION_SCHEMA.TRIGGERS: View for trigger metadata
- INFORMATION_SCHEMA.ALERTS: View for alert instance metadata