Skip to content
DevOps AI ToolKit
Newsletter
All prompts
AI for Grafana Difficulty: Intermediate ClaudeChatGPT

Grafana SQL Data Source (Postgres/MySQL) Dashboards Prompt

Build Grafana dashboards on Postgres or MySQL data sources using SQL macros ($__timeFilter, $__timeGroup) for time series and tables.

Target user
SREs and data engineers turning relational data into Grafana panels
Difficulty
Intermediate
Tools
Claude, ChatGPT

The prompt

You are a senior observability engineer fluent in Grafana's SQL data sources and its macro system.

I will provide:
- The database engine (Postgres or MySQL) and schema
- Tables/columns to visualize
- Panels or SLOs to build

Your job:

1. **Configure the datasource** with a least-privilege read-only role and TLS; set `sslmode` for Postgres and the connection limits.
2. **Time series queries**: return a `time` column plus metric columns, and always bound with `$__timeFilter(created_at)` and bucket with `$__timeGroup(created_at, $__interval)` (Postgres) or `$__timeGroupAlias` for named output.
3. **Table queries**: use Format = Table, alias columns cleanly, and rely on transformations for joins across queries.
4. **Macros**: apply `$__timeFrom()`, `$__timeTo()`, `$__unixEpochFilter()`, and `$__interval` correctly per engine — Postgres and MySQL differ.
5. **Template variables**: drive dropdowns with SQL like `SELECT DISTINCT service FROM deploys ORDER BY 1` and reference them as `WHERE service IN ($service)`.
6. **Parameterization safety**: quote multi-value variables and avoid SQL injection by using `${var:sqlstring}` formatting.
7. **Performance**: index the time column, avoid `SELECT *`, and pre-aggregate with `$__timeGroup` rather than pulling raw rows.
8. **Provisioning**: define the datasource in YAML with `secureJsonData` for the password.

Mark DESTRUCTIVE: granting write/DDL privileges to the Grafana role, running unbounded queries without $__timeFilter, pointing at a primary instead of a read replica.

---

Engine/schema: [DESCRIBE]
Tables/columns: [DESCRIBE]
Panels/SLOs: [DESCRIBE]

Why this prompt works

Grafana’s SQL data sources are powerful but the macro layer ($__timeFilter, $__timeGroup) is where people slip — they either omit it and full-scan a table, or use the Postgres form against MySQL. This prompt forces engine-aware macro usage, read-only auth, and pre-aggregation so relational panels stay fast and safe.

How to use it

  1. Name the engine so the assistant uses the correct macro variants.
  2. Share the schema and indexes so it can pre-aggregate against indexed columns.
  3. Describe the panel type (time series vs table) to pick the Format setting.
  4. Ask for the read-only grant and provisioning YAML.

Useful commands

-- Least-privilege read-only role (Postgres)
CREATE ROLE grafana_ro LOGIN PASSWORD 'REDACTED';
GRANT CONNECT ON DATABASE appdb TO grafana_ro;
GRANT USAGE ON SCHEMA public TO grafana_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO grafana_ro;
# Health-check the datasource via Grafana API
curl -s -H "Authorization: Bearer $GRAFANA_TOKEN" \
  http://localhost:3000/api/datasources/uid/pg-app/health

Example config

# provisioning/datasources/postgres.yaml
apiVersion: 1
datasources:
  - name: App Postgres
    type: postgres
    uid: pg-app
    access: proxy
    url: replica.db.internal:5432
    user: grafana_ro
    jsonData:
      database: appdb
      sslmode: require
      postgresVersion: 1600
      maxOpenConns: 5
      timescaledb: false
    secureJsonData:
      password: ${PG_GRAFANA_PASSWORD}
-- Time series panel: request rate per service, bucketed
SELECT
  $__timeGroup(created_at, $__interval) AS time,
  service,
  count(*) AS requests
FROM request_log
WHERE $__timeFilter(created_at)
  AND service IN (${service:sqlstring})
GROUP BY 1, 2
ORDER BY 1;

Common findings this catches

  • Full table scans → missing $__timeFilter.
  • Wrong buckets$__timeGroup variant mismatched to engine.
  • Production impact → datasource on primary instead of replica.
  • Injection risk → multi-value variable not ${var:sqlstring}.
  • Slow panels → no index on the time column.
  • Broken table joins → should use transformations, not sub-queries.
  • Credential leak → password in jsonData.

When to escalate

  • Query load impacting the database — involve DBAs and add a dedicated replica.
  • Schema redesign for analytics — data engineering.
  • Row-level security or PII exposure in panels — security review.

Related prompts

Newsletter

Free: the DevOps AI Incident-Triage Cheat Sheet

Subscribe and we’ll send you the one-page cheat sheet — plus weekly AI prompts, automation ideas, and tool reviews for infrastructure engineers. One email a week. No spam, unsubscribe anytime.

  • AI Incident-Triage Cheat Sheet (PDF)
  • Access to 2,104 DevOps AI prompts
  • One practical workflow email per week