Skip to main content

Analytics Query Language

Work in Progress

This page documents the SQL meta-comment language used by the Analytics / Query Explorer. The feature and its syntax are under active development and may change.

The Query Explorer uses a lightweight meta-comment language embedded in SQL comments to drive chart rendering, drill-down navigation, and time-range filtering. Any ClickHouse SQL query can become a fully interactive preset by adding a few -- @directive lines at the top.

Directives

@meta - Query metadata

Defines the query's identity and display properties.

-- @meta: title='Memory Usage Trend' group='Resources' description='Memory usage over the last 24 hours' interval='1 DAY'
ParameterRequiredDescription
titleYesDisplay name shown in the sidebar and query header
groupYesCategory tab (Overview, Inserts, Selects, Parts, Merges, Resources, Advanced Dashboard, Self-Monitoring, or any custom name)
descriptionNoShort description shown as a tooltip / subtitle
intervalNoDefault time range, e.g. 1 DAY, 2 HOUR, 7 DAY. Used with {{time_range}} placeholders

@chart - Chart configuration

Tells the explorer how to visualise the result set.

-- @chart: type=bar group_by=table value=bytes_size style=3d
ParameterRequiredDescription
typeYesChart type: bar, line, pie, area, grouped_bar, stacked_bar, grouped_line
group_byYesColumn name to use for the X-axis / category grouping
valueYesColumn name(s) for the Y-axis. Can be a single column or comma-separated list (e.g. value=p50,p95,p99)
seriesNoColumn name used for series splitting (for grouped_bar, stacked_bar, grouped_line)
styleNo2d (default SVG/recharts) or 3d (Three.js)
unitNoUnit suffix for value axis ticks, e.g. ms, s, MB, %. Time units (ms, s) auto-scale (e.g. 1400 ms → 1.4 s)
orientationNohorizontal (default for grouped/stacked bars) or vertical (shorthand v). Controls bar direction — horizontal puts labels on the left for readability
colorNoOverride the default chart color with a hex value (e.g. #f59e0b)

@drill - Drill-down navigation

Enables click-to-drill: clicking a chart segment navigates to another query, passing the clicked value as a filter.

-- @drill: on=database into='Table Sizes'
ParameterRequiredDescription
onYesColumn whose clicked value is passed to the target query
intoYesTitle of the target query to navigate to

Makes a table column clickable. Clicking a cell value opens a modal popup that runs a target query with the clicked value passed as a drill parameter. Unlike @drill which navigates away, @link keeps your current view and overlays the results.

-- @link: on=query_hash into='App Query Executions'
ParameterRequiredDescription
onYesColumn whose clicked value is passed to the target query
intoYesTitle of the target query to open in the popup

The target query receives the clicked value via the standard {{drill:column | fallback}} or {{drill_value:column | fallback}} placeholders.

@cell - Table cell decoration

Decorates table columns with visual styles. Each @cell: line targets one column with one decoration type. Multiple @cell: lines can target the same column (e.g. gauge + rag).

ParameterRequiredDescription
columnYesColumn name to decorate
typeYesDecoration type: rag, gauge, or sparkline

type=rag — Red / Amber / Green coloring

Applies conditional coloring to table cells. Only affects table view.

Numeric (ascending — lower is better):

-- @cell: column=avg_bytes_read type=rag green<2000 amber<40000

Numeric (descending — higher is better):

-- @cell: column=uptime_days type=rag green>30 amber>7

Text mode — match exact string values:

-- @cell: column=status type=rag green=ok,healthy amber=degraded red=error,down

type=gauge — Inline horizontal bar

Renders a column as a horizontal gauge bar in the table. Combine with type=rag on the same column for colored bars.

-- @cell: column=used_pct type=gauge max=100 unit=%
-- @cell: column=used_pct type=rag green<70 amber<85
-- @cell: column=disk_used type=gauge max=disk_total unit=TiB
ParameterRequiredDescription
maxYesBar's 100% value — a fixed number (e.g. 100) or another column name (e.g. disk_total)
unitNoUnit suffix displayed beside the value

type=sparkline — Inline trend line

Renders a column as a tiny SVG trend in the table. The column should contain an array of numeric values (e.g. from groupArray()).

-- @cell: column=disk_delta type=sparkline ref=0
-- @cell: column=query_rate type=sparkline color=#f59e0b fill=true
ParameterRequiredDescription
refNoHorizontal reference line value (e.g. 0 for delta charts)
colorNoHex color for the sparkline stroke
fillNotrue to fill the area under the line

Multiple decorations on different columns:

-- @cell: column=memory_pct type=gauge max=100 unit=%
-- @cell: column=memory_pct type=rag green<60 amber<85
-- @cell: column=cpu_pct type=gauge max=100 unit=%
-- @cell: column=disk_delta type=sparkline ref=0

Template placeholders

{{time_range}}

Replaced at execution time with a ClickHouse time expression based on the user-selected time range or the @meta interval default.

WHERE event_time > {{time_range}}

When using the time picker's custom range, {{time_range}} resolves to a toDateTime('...') expression with both start and end bounds injected automatically.

{{drill:column | fallback}}

Replaced with a filter condition when the query is reached via drill-down, or with the fallback expression otherwise.

WHERE {{drill:database | 1=1}}
  • When drilled into with database = 'nyc_taxi'WHERE database = 'nyc_taxi'
  • When opened directly → WHERE 1=1

{{drill_value:column | fallback}}

Like {{drill:column | fallback}} but resolves to just the quoted value instead of a full equality condition. Useful when the drill parameter needs a custom expression (e.g. computed column matching):

WHERE lower(hex(normalized_query_hash)) = {{drill_value:query_hash | ''}}
  • When linked/drilled with query_hash = '52794d32e666dd45'WHERE lower(hex(normalized_query_hash)) = '52794d32e666dd45'
  • When opened directly → WHERE lower(hex(normalized_query_hash)) = ''

{{cluster_aware:db.table}}

On a single-node setup, resolves to the bare table reference db.table. On a cluster, wraps it with clusterAllReplicas('cluster_name', db.table) so that per-node tables like system.query_log are fanned out to all replicas. Queries using this should deduplicate with GROUP BY since replicas may return overlapping rows.

SELECT query, count()
FROM {{cluster_aware:system.query_log}}
WHERE event_time > {{time_range}}
GROUP BY query

{{cluster_name}}

Resolves to the quoted cluster name on a cluster, or an empty string on single-node. Useful for conditional logic or display.

Source attribution

A -- Source: comment (not a directive) adds an attribution link to the query card, typically pointing to ClickHouse docs or knowledge base articles.

-- Source: https://clickhouse.com/docs/operations/system-tables/parts

Full example

-- @meta: title='Database Sizes' group='Overview' description='Total disk usage per database'
-- @chart: type=pie group_by=database value=total_bytes style=3d
-- @drill: on=database into='Table Sizes'
-- @cell: column=total_bytes type=rag green<1000000000 amber<10000000000
SELECT
database,
sum(bytes_on_disk) AS total_bytes
FROM system.parts
WHERE active
GROUP BY database
ORDER BY total_bytes DESC

This query appears in the Overview group, renders as a 3D pie chart, clicking a slice drills into the "Table Sizes" query filtered to that database, and in table view the total_bytes column is color-coded green/amber/red based on size.