Understanding how queries flow through Grafana explains auth problems, alerting limitations and what custom plugins can do.
Grafana is built from plugins, including its core data sources and panels:
- Panel plugins are React components that render data frames.
- Data source plugins translate queries into requests to a backend system and return data frames, Grafana's columnar data structure.
- App plugins bundle pages, dashboards and data sources into one product (for example Kubernetes monitoring apps).
A plugin has a frontend (TypeScript/React) and optionally a backend written in Go with the plugin SDK. Backend plugins run as separate processes that Grafana talks to over gRPC. Only data sources with a backend can be used by alerting, server-side expressions, public dashboards and caching, because those run without a browser.
Query flow for a backend data source: the panel sends a request to Grafana's /api/ds/query endpoint; Grafana checks permissions, attaches the stored credentials, and calls the plugin backend, which queries the system and returns frames. Credentials never reach the browser. Older frontend-only data sources used the data source proxy (/api/datasources/proxy/...): the browser builds the request and Grafana forwards it with secrets added. Direct browser access mode is deprecated.
Plugins can execute code on the server, so Grafana verifies signatures: unsigned plugins load only if explicitly allowed with allow_loading_unsigned_plugins. Install plugins with grafana cli plugins install or the GF_PLUGINS_PREINSTALL variable.
Example
# Install a plugin (restart Grafana afterwards)
grafana cli plugins install grafana-clock-panel
# or in Docker:
docker run -d -p 3000:3000 \
-e GF_PLUGINS_PREINSTALL=grafana-clock-panel \
grafana/grafana:13.2.0
# Every panel query goes through the backend query API:
curl -s -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
https://grafana.example.com/api/ds/query -d '{
"from": "now-1h", "to": "now",
"queries": [{"refId": "A", "datasource": {"uid": "prom-main"},
"expr": "sum(up)", "instant": true}]}'
# {"results":{"A":{"status":200,"frames":[{"schema":{...},"data":{"values":[[...],[3]]}}]}}}Remember
- Panel, data source and app plugins; data travels as data frames
- Backend plugins run server-side over gRPC and enable alerting and expressions
- Unsigned plugins are blocked unless explicitly allowed
Watch out for
- Choosing a frontend-only data source plugin and discovering it can't be used for alerting.