Dashboards
Build and share ClickHouse dashboards with SQL-powered panels
Dashboards let you build visual panels backed by SQL queries against your ClickHouse data. Each panel supports time-range interpolation, multiple chart types, and a grid layout.
Included in the free Community edition.
Overview
Each dashboard has:
- A name and description
- One or more panels — each with its own SQL query, chart type, and layout position
- A shared time range — applied to all panels simultaneously
A default "System Overview" dashboard is auto-created on first access.
Dashboard CRUD
# List all dashboards
GET /api/dashboards
# Create
POST /api/dashboards
{ "name": "Production Metrics", "description": "Key production KPIs" }
# Get dashboard + panels
GET /api/dashboards/{id}
# Update
PUT /api/dashboards/{id}
{ "name": "Updated Name" }
# Delete (cascades to all panels)
DELETE /api/dashboards/{id}Panel Types
| Type | Use Case |
|---|---|
table | Tabular data display (default) |
stat | Single metric / KPI card |
timeseries | Line/area chart over time (via uplot) |
bar | Bar chart (via uplot) |
Panel Editor
Each panel is configured with:
| Field | Description | Default |
|---|---|---|
| Name | Panel title | Required |
| Panel Type | table, stat, timeseries, or bar | table |
| Query | SQL query (supports template variables) | Required |
| Config | Chart options (JSON): xColumn, yColumns, colors, legendPosition | {} |
Chart Config
{
"chartType": "timeseries",
"xColumn": "timestamp",
"yColumns": ["value", "count"],
"colors": ["#3b82f6", "#ef4444"],
"legendPosition": "bottom"
}Layout
Panels are arranged on a 12-column grid. Each panel stores its position:
| Field | Description | Default |
|---|---|---|
layout_x | Column offset (0-11) | 0 |
layout_y | Row offset | 0 |
layout_w | Width in columns | 6 |
layout_h | Height in rows | 4 |
Drag and resize panels in the UI to adjust layout. Positions are saved automatically.
Time Range
A shared time-range selector applies to all panels in the dashboard.
Presets
1h, 6h, 24h, 7d, 30d, or custom ISO timestamps.
Persisted in localStorage (ch-ui-dashboard-time-range, default 1h).
Template Variables
Panel queries support time-range macros that are interpolated before execution:
| Variable | Description | Example |
|---|---|---|
$__from | Start timestamp (ISO 8601) | 2026-03-15T00:00:00Z |
$__to | End timestamp (ISO 8601) | 2026-03-15T01:00:00Z |
$__interval | Bucket interval | 1m, 5m |
$__rate | Rate query modifier | — |
Example Query
SELECT
toStartOfInterval(timestamp, INTERVAL $__interval) AS ts,
count() AS events
FROM default.events
WHERE timestamp BETWEEN '$__from' AND '$__to'
GROUP BY ts
ORDER BY tsPanel Query Execution
Panel queries use a dedicated endpoint with time-range interpolation:
POST /api/dashboards/query{
"query": "SELECT ...",
"timeout": 30,
"time_range": { "from": "2026-03-15T00:00:00Z", "to": "2026-03-15T01:00:00Z" },
"time_field": "timestamp",
"max_data_points": 1000
}Timeout max: 5 minutes. max_data_points controls downsampling (default 1000).
The response includes the interpolated query and the resolved variable values.
Panel CRUD
# Create panel
POST /api/dashboards/{id}/panels
{
"name": "Events per Hour",
"panel_type": "timeseries",
"query": "SELECT toStartOfHour(timestamp) AS ts, count() AS n FROM events WHERE timestamp > '$__from' GROUP BY ts ORDER BY ts",
"config": "{\"xColumn\":\"ts\",\"yColumns\":[\"n\"]}",
"layout_x": 0, "layout_y": 0, "layout_w": 12, "layout_h": 4
}
# Update panel
PUT /api/dashboards/{id}/panels/{panelId}
{ "name": "Updated Title", "query": "..." }
# Delete panel
DELETE /api/dashboards/{id}/panels/{panelId}