Grafana Table Panel Transformations Prompt
Shape Grafana table panels with transformations — join, organize, group-by, and calculations — to turn raw query frames into readable tables.
- Target user
- Dashboard authors building summary and inventory tables
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT
The prompt
You are a senior observability engineer who shapes Grafana table panels with the transformation pipeline so multiple queries become one clean, sortable table. I will provide: - The queries/frames feeding the panel - The desired columns and per-row grouping - Any joins across data sources or metrics Your job: 1. **Order matters**: transformations run top-to-bottom; sequence them (reduce/group first, then join, then organize) — reordering changes the output. 2. **Reduce time series**: apply `Reduce` (calc: last, max, mean) or `Group by` to collapse time series into one value per series before display. 3. **Join**: use `Merge` to stack frames, or `Join by field` (outer/inner) to combine metrics on a shared key (e.g. `pod`) into one row. 4. **Group by + calc**: `Group by` on a label with aggregations (count, sum, mean) per numeric field to build summaries. 5. **Organize fields**: use `Organize fields` to rename, reorder, and hide columns — this is where you make labels human-readable. 6. **Filter/derive**: `Filter data by values`, `Filter by name`, and `Add field from calculation` (binary ops, e.g. errors/total) to compute derived columns like error rate. 7. **Display**: set cell display mode (colored background/gauge), per-column units/thresholds via field overrides, and enable column filters + pagination. 8. **Labels to fields**: use `Labels to fields` so Prometheus labels become columns; combine with `Extract fields` for JSON blobs. Mark DESTRUCTIVE: none — transformations are client-side and non-mutating. Flag `Filter` steps that silently drop rows a viewer expects to see. --- Queries/frames: [DESCRIBE] Desired columns/grouping: [DESCRIBE] Joins needed: [DESCRIBE]
Why this prompt works
The table panel’s power is its transformation pipeline, but transformations are order-dependent and easy to misuse — an inner join silently drops rows, a filter hides data, a reduce masks spikes. This prompt sequences the pipeline correctly (reduce/group, then join, then organize) and calls out the silent data-loss steps so the table stays trustworthy.
How to use it
- List the frames each query returns.
- Name the final columns and the row key.
- Sequence transformations deliberately, top-to-bottom.
- Verify row counts after any join or filter.
Useful commands
# Inspect a panel's transformation pipeline
curl -s -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/api/dashboards/uid/inventory \
| jq '.dashboard.panels[] | select(.type=="table") | .transformations'
Example config
Table panel joining two metrics per pod and computing error rate:
{
"type": "table",
"title": "Pods: traffic and error rate",
"targets": [
{ "refId": "A", "expr": "sum by (pod) (rate(requests_total[5m]))", "format": "table", "instant": true },
{ "refId": "B", "expr": "sum by (pod) (rate(errors_total[5m]))", "format": "table", "instant": true }
],
"transformations": [
{ "id": "labelsToFields", "options": {} },
{ "id": "joinByField", "options": { "byField": "pod", "mode": "outer" } },
{ "id": "calculateField", "options": {
"mode": "binary", "alias": "error_rate",
"binary": { "left": "Value #B", "operator": "/", "right": "Value #A" } } },
{ "id": "organize", "options": {
"renameByName": { "Value #A": "req/s", "Value #B": "err/s" },
"indexByName": { "pod": 0, "req/s": 1, "err/s": 2, "error_rate": 3 },
"excludeByName": { "Time": true } } }
],
"fieldConfig": {
"overrides": [
{ "matcher": { "id": "byName", "options": "error_rate" },
"properties": [
{ "id": "unit", "value": "percentunit" },
{ "id": "custom.cellOptions", "value": { "type": "color-background" } },
{ "id": "thresholds", "value": { "mode": "absolute", "steps": [
{ "color": "green", "value": null }, { "color": "red", "value": 0.05 } ] } }
] }
]
}
}
Common findings this catches
- Missing rows → inner join or value filter dropped them.
- Wrong aggregates →
Group byused sum where mean was needed. - Unreadable columns → labels never mapped via Organize/Labels-to-fields.
- Masked spikes → reduced to
lastinstead ofmax. - Order bugs → join placed before reduce.
- Falsely hidden data → sensitive column hidden, not excluded from the frame.
When to escalate
- Cross-datasource joins that strain the browser — move logic to the backend.
- Complex derived tables reused widely — library panel + documentation.
- Correctness disputes on aggregations — data/service owner.
Related prompts
-
Grafana Data Links and Drilldowns Prompt
Wire Grafana data links and drilldowns so panels jump to related dashboards, Explore, or external tools carrying filter context.
-
Grafana State Timeline and Status History Prompt
Design Grafana State timeline and Status history panels to visualize discrete states like up/down, deploy phases, and health over time.
-
Grafana Value Mappings and Thresholds Prompt
Configure Grafana value mappings, thresholds, and color schemes so panels turn raw numbers into clear, consistent status signals.