ClickHouse annotations
Annotations overlay event markers on your dashboard panels. You can use ClickHouse SQL queries to create annotations that mark deployments, alerts, errors, or other events from your data.
The plugin uses Grafana’s default annotation support: you write a ClickHouse query that returns a time column and a text column. Grafana positions each row as an annotation on the time axis and shows the text when you hover or click.
For an overview of annotations in Grafana, see Annotate visualizations.
Before you begin
- Configure the ClickHouse data source.
- Ensure your ClickHouse user has read access to the tables you use in your annotation query.
Create an annotation query
To add a ClickHouse annotation to a dashboard:
- Open the dashboard where you want to add annotations.
- Click Dashboard settings (gear icon) in the top navigation.
- Select Annotations in the left menu.
- Click Add annotation query.
- Enter a Name for the annotation (for example, “Deployments”, “Errors”).
- In the Data source drop-down, select your ClickHouse data source.
- In the Query field, enter a ClickHouse SQL query that returns the required columns (see Query requirements).
- Use the Column mappings section to map your query columns to Time, Text, and optionally Tags (if your column names differ from Grafana’s defaults).
- Click Apply to save.
Query requirements
Your SQL query must return at least a time column and a text column. Grafana uses these to place and label each annotation.
Always restrict the query to the dashboard time range so annotations load quickly. Use the $__timeFilter(column) macro in your WHERE clause; see the ClickHouse query editor Macros section.
Annotation query examples
The following examples show common patterns. Replace the table and column names with your own.
Application events (e.g. deployments or status changes):
SELECT
event_time AS time,
message AS text,
environment AS tag
FROM my_app.events
WHERE $__timeFilter(event_time)
AND event_type IN ('deployment', 'status_change')
ORDER BY event_time DESC
LIMIT 100Query log events (e.g. long-running or failed queries from ClickHouse system tables):
SELECT
event_time AS time,
concat(type, ': ', substring(query, 1, 80)) AS text,
initial_user AS tag
FROM system.query_log
WHERE $__timeFilter(event_time)
AND type IN ('QueryFinish', 'ExceptionWhileProcessing')
ORDER BY event_time DESC
LIMIT 100Errors or alerts from a custom table:
SELECT
timestamp AS time,
concat(severity, ' - ', message) AS text,
service AS tag
FROM my_app.alerts
WHERE $__timeFilter(timestamp)
ORDER BY timestamp DESC
LIMIT 100Best practices
- Use a time filter — Include
$__timeFilter(your_time_column)in the WHERE clause so the query only returns data in the dashboard time range. - Limit results — Use
LIMIT(for example, 100) so the query stays fast and the dashboard does not show too many markers. - Meaningful text — Use
concat()or similar so the text column is clear (e.g. event type plus a short description). - Use tags — Return one or more tag columns (e.g. environment, service, user) so users can filter annotations in the dashboard.
- Descriptive names — Give the annotation a clear name (e.g. “Production deployments”, “Query errors”) so dashboard users know what it represents.
Next steps
- ClickHouse query editor — Macros such as
$__timeFilterand building queries. - Annotate visualizations — Grafana annotation options (colors, which panels show annotations, filters).
- Troubleshoot ClickHouse data source issues — Common errors and solutions.


