docs/sources/datasources/prometheus/query-editor/_index.md
The Prometheus query editor lets you write PromQL queries against your Prometheus-compatible data sources. It includes a visual query builder for constructing queries without writing PromQL, a code editor with autocomplete and syntax highlighting, and configurable output formats for different visualization types.
You can access the query editor from the Explore page or from any dashboard panel by clicking the panel title and selecting Edit. For general documentation on querying data sources in Grafana, refer to Query and transform data. For more information about PromQL, see Querying Prometheus.
The query editor has two modes:
Grafana synchronizes both modes, allowing you to switch between them. Grafana also displays a warning message if it detects an issue with the query while switching modes.
The following options are available in both Builder and Code modes. They control how the query is executed and how results are displayed.
{{< figure src="/static/img/docs/prometheus/options.png" max-width="500px" class="docs-image--no-shadow" caption="Query options" >}}
Controls the display name for time series in the panel legend.
{{hostname}} is replaced with the value of the hostname label. To switch to a different legend mode, clear the input and click outside the field.Sets the minimum interval between data points returned by the query. For example, setting this to 1h means data is returned at hourly intervals at minimum. This setting supports the $__interval and $__rate_interval macros.
{{< admonition type="note" >}} The time range of the query is aligned to the step size, which may adjust the actual start and end times of the returned data. {{< /admonition >}}
Determines how query results are interpreted and displayed in a panel.
Determines the query type.
Transform property set to Constant. For more information, refer to Time Series Transform option.{{< admonition type="note" >}}
Grafana adjusts the query time range to align with the dynamically calculated step interval. This ensures consistent metric visualization and supports Prometheus result caching. However, this alignment can cause minor visual differences, such as a slight gap at the graph's right edge or a shifted start time. For example, a 15s step aligns timestamps to Unix times divisible by 15 seconds. A 1w Min step aligns the range to the start of the week (Thursday at 00:00 UTC in Prometheus).
{{< /admonition >}}
Toggle on to include exemplars in the graph. Exemplars link aggregated metric data to specific trace examples, letting you jump from a spike directly to a relevant trace. For more information, see Introduction to exemplars.
{{< admonition type="note" >}} Exemplars are not available with Instant query types. {{< /admonition >}}
Builder mode helps you build queries using a visual interface. This option is best for users who have limited experience with PromQL.
Builder mode contains the following components:
Kick start your query — Click to view predefined operation patterns that help you quickly build queries with multiple operations:
Click the arrow next to each to see the available options.
Explain — Toggle on to display a step-by-step explanation of all query components and operations.
{{< figure src="/static/img/docs/prometheus/explain-results.png" max-width="500px" class="docs-image--no-shadow" caption="Explain results" >}}
{{< figure src="/static/img/docs/prometheus/metrics-and-labels.png" max-width="500px" class="docs-image--no-shadow" caption="Metric and label filters" >}}
+ button to add filters and the x button to remove them. When a metric is selected, the data source requests available labels and their values from the server.{{< figure src="/static/img/docs/prometheus/operations.png" max-width="500px" class="docs-image--no-shadow" caption="Operations" >}}
Click + Operations to add operations to your query. The query editor groups operations into the following categories:
sum, avg, count, min, max, etc.rate, increase, irate, avg_over_time, etc.abs, ceil, histogram_quantile, etc.acos, asin, atan, etc.time, timestamp, day_of_week, etc.All operations display function parameters beneath the operation header. Some operations allow you to apply specific labels (for example, by or without clauses).
{{< figure src="/static/img/docs/prometheus/use-function-by-label-9-5.png" max-width="500px" class="docs-image--no-shadow" caption="Functions and labels" >}}
If you add an operation in a way that would create an invalid query, the query editor automatically places it in the correct position to maintain a valid query structure.
The query editor can detect which operations are most appropriate for certain selected metrics. When it does, it displays a hint next to the + Operations button. Click the hint to add the suggested operation.
{{< figure src="/static/img/docs/prometheus/hint-example.png" max-width="500px" class="docs-image--no-shadow" caption="Hint" >}}
{{< figure src="/static/img/docs/prometheus/screenshot-grafana-prometheus-metrics-explorer-2.png" max-width="500px" class="docs-image--no-shadow" caption="Metrics explorer" >}}
Click the book icon next to the metric selector to open the Metrics explorer. It displays all metrics in a paginated list showing the name, type, and description for each metric.
The following options are available under Additional Settings:
{{< admonition type="note" >}} The Metrics explorer (Builder mode) and Metrics browser (Code mode) are separate components. The Metrics explorer does not browse labels, but the Metrics browser can display all labels on a metric. {{< /admonition >}}
Code mode is for experienced Prometheus users who prefer writing PromQL directly. For more information about PromQL, see Querying Prometheus.
{{< figure src="/static/img/docs/prometheus/code-mode.png" max-width="500px" class="docs-image--no-shadow" caption="Code mode" >}}
Code mode provides:
The Metrics browser helps you build basic queries by exploring available metrics and labels.
{{< figure alt="Prometheus query editor metrics browser" src="/media/docs/prometheus/Metrics-browser-V10-prom-query-editor.png" caption="Metrics browser" >}}
rate(...[$__rate_interval]).{{< admonition type="note" >}} If you don't remember the exact metric name, start by selecting a few labels to filter the list and narrow down your options. {{< /admonition >}}
All lists in the Metrics browser include a search field. In the Values section, a single search field filters across all selected labels.
The following examples show frequently used PromQL patterns. Each example includes the PromQL expression and guidance on which query options to use.
Calculate the per-second rate of HTTP requests, broken down by service:
sum(rate(http_requests_total[$__rate_interval])) by (service)
| Option | Setting |
|---|---|
| Legend | {{service}} (Custom) |
| Type | Range |
| Min step | Leave empty (uses $__interval) |
Builder mode steps: Select http_requests_total → Add operation Range functions > Rate → Add operation Aggregations > Sum → Set by label to service.
Calculate the percentage of requests that returned 5xx errors:
sum(rate(http_requests_total{status=~"5.."}[$__rate_interval])) / sum(rate(http_requests_total[$__rate_interval])) * 100
| Option | Setting |
|---|---|
| Legend | Error rate % (Custom) |
| Type | Range |
| Format | Time series |
Calculate the 95th percentile request duration from a histogram metric:
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[$__rate_interval])) by (le))
| Option | Setting |
|---|---|
| Legend | p95 latency (Custom) |
| Type | Range |
Builder mode steps: Select http_request_duration_seconds_bucket → Add Range functions > Rate → Add Aggregations > Sum with by label le → Add Functions > Histogram quantile with value 0.95.
Calculate average CPU usage percentage, grouped by instance:
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[$__rate_interval])) * 100)
| Option | Setting |
|---|---|
| Legend | {{instance}} (Custom) |
| Type | Range |
| Min step | 15s (match your scrape interval) |
Use multiple queries and expressions to calculate derived values. In the query editor, add multiple queries (A, B) and a math expression (C):
Query A — Total memory:
node_memory_MemTotal_bytes
Query B — Available memory:
node_memory_MemAvailable_bytes
Expression C — Percentage available (click + Expression → Math):
$B / $A * 100
Set queries A and B to Type: Instant and hide them from visualization (click the eye icon). Display only expression C.
A simple alert query that fires when a scrape target is down:
up{job="my-service"} == 0
| Option | Setting |
|---|---|
| Type | Both |
| Format | Time series |
{{< admonition type="note" >}}
Alert queries don't support template variables ($variable). Use fixed label values when writing queries intended for alert rules.
{{< /admonition >}}
The query inspector helps you debug queries that return unexpected results or no data. To open it:
Common debugging steps:
/graph) to rule out Grafana-specific issues.High-cardinality metrics (those with many unique label combinations) can cause queries to timeout or exceed memory limits when queried over long time ranges. Follow these practices to query high-cardinality data effectively:
sum(), avg(), or count() to reduce the number of series before applying other operations. For example, sum(rate(metric[5m])) by (service) is far cheaper than querying all individual pod-level series.namespace, cluster, or job rather than querying all labels at once.5m or 15m) to reduce the number of data points requested.If your queries hit memory or sample limits, refer to Memory limit exceeded for high-cardinality queries.
The following behaviors are frequently misinterpreted as bugs but are expected Prometheus behavior.
increase() returns fractional values on integer countersincrease() uses linear interpolation to estimate the increase over the specified time window. Because scrape timestamps rarely align exactly with the window boundaries, the result is interpolated — which produces fractional values even for integer counters.
This is expected. If you need integer results, wrap the expression in ceil() or floor():
ceil(increase(http_requests_total[5m]))
rate() appears to grow over timeIf rate() shows an ever-increasing value instead of a steady per-second rate, the most common cause is multiple instances writing to the same time series without unique distinguishing labels. Prometheus merges these into a single series with an artificially growing counter.
To fix this, ensure every scrape target has unique labels (for example, instance, pod, or node). Then aggregate explicitly:
sum(rate(http_requests_total[5m])) by (job)
If you see this after a deployment or scaling event, verify your service discovery is assigning unique instance labels to each target.
When a monitored process restarts, its counters reset to zero. Prometheus handles this with counter reset detection — rate() and increase() account for resets and don't produce negative values. However, you may still see a brief spike at the reset point because the first scrape after a restart reports the full counter value accumulated since the restart.
To minimize the visual impact:
rate() over a window that spans multiple scrape intervals (for example, $__rate_interval) so the spike is averaged out.avg_over_time() on top of rate().If adding a label filter doesn't reduce the result count, you may have high-cardinality labels (such as request_id or user_id) on your metrics. Use the Prometheus TSDB status page (/tsdb-status) or the Grafana Metrics explorer to identify high-cardinality label combinations, then either drop unnecessary labels at scrape time or use aggregation in your queries.
$namespace or $job to create dynamic, reusable dashboards.