Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
Query Prometheus by writing a PromQL expression in the web console or sending that expression to the HTTP API. Begin with a metric selector, narrow it with label matchers, add a range selector when a function needs a history of samples, and then aggregate or compare the resulting series. Use the Table view to verify an instant result before putting the expression on a graph, dashboard, alert, or script.
PromQL is Prometheus’s functional query language for selecting and aggregating time-series data in real time. The same expression can be evaluated once at a timestamp (an instant query) or repeatedly at fixed intervals across a start and end time (a range query). Understanding that distinction, along with metric types, labels, and result cardinality, prevents most confusing Prometheus results.
Recommended Free Tools
What PromQL queries actually return
A Prometheus time series is identified by a metric name plus its set of labels. Each sample has a timestamp and a numeric value. PromQL evaluates an expression against those series and returns one of four documented data types:
| Type | What it contains | Typical use |
|---|---|---|
| Instant vector | One sample for each matching series at one evaluation timestamp | Current values, rates at “now,” and dashboard panels |
| Range vector | Samples for each matching series over a lookback interval | Input to functions such as rate() and increase() |
| Scalar | One numeric value | Constants, arithmetic, and percentages |
| String | A string value; it is currently unused in the documented expression model | Not normally used in PromQL queries |
An instant vector is not the same thing as a range vector containing one sample. The distinction matters because functions and operators require particular input types. A range query’s root expression must produce a scalar or instant vector; the range query engine evaluates that expression once per step and returns the sequence of results.
#1 Best Overall
Prometheus’s documentation describes PromQL as a language that lets users select and aggregate time-series data in real time. That makes a query more than a database lookup: functions can calculate rates, arithmetic can derive percentages, and aggregators can reduce thousands of series to the dimensions that matter.
Run your first query in the Prometheus web UI
The expression browser is the fastest place to learn what your installation actually exposes. Metric names and labels depend on the exporters and application instrumentation you have deployed, so start by inspecting real data rather than copying a selector whose labels do not exist in your environment.
- Open the Prometheus web interface and select the query or expression page.
- Enter
upand execute it. The result shows whether each discovered target is currently reporting. If your deployment uses a different set of scrape targets, the series and labels will differ. - Stay in the Table view while exploring. It performs an instant query and shows the labels and value for each returned series.
- Once the selector is correct, switch to the Graph view to evaluate it repeatedly over a time interval. Graph view is intended for range queries.
- Read the label set on every returned series before adding a function or aggregation. Those labels determine whether the result is one series, one series per service, or thousands of separate series.
The tabular view is also a safety check. A bare selector for a high-cardinality metric can expand to a very large result set, making a query expensive and difficult to interpret. Narrow it before building a dashboard panel or alert.
Build a metric selector
A metric name by itself selects every series with that name. For example:
http_requests_total
To select only series matching labels, put comma-separated matchers in braces:
http_requests_total{job="prometheus",group="canary"}
The four matcher operators are:
| Operator | Meaning | Example |
|---|---|---|
= |
Label equals an exact value | {job="prometheus"} |
!= |
Label does not equal a value | {job!="prometheus"} |
=~ |
Label matches a regular expression | {job=~"api|worker"} |
!~ |
Label does not match a regular expression | {job!~"test|canary"} |
PromQL regular-expression matchers use RE2 syntax and are fully anchored. In practice, job=~"api" matches the complete label value api, not every value containing the letters “api.” To match a value containing that text, write a pattern such as .*api.*. Check your installation’s labels in the table result before relying on a pattern.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Matchers can be combined to make a selector precise:
http_requests_total{job="api",instance=~"web-[0-9]+:8080",status!="200"}
A selector with no matching series is not necessarily a syntax error. It can mean the metric name, label name, or label value is different from what your instrumentation emits, or that no sample is available at the evaluation time. Test the metric name alone, then add one matcher at a time.
Use range selectors for recent history
Appending a duration in square brackets turns an instant-vector selector into a range vector. This example selects the samples from the last five minutes for every matching series:
http_requests_total{job="prometheus"}[5m]
Range intervals are left-open and right-closed: the start boundary is excluded and the end boundary is included. Common duration units include seconds (s), minutes (m), hours (h), days (d), weeks (w), and years (y). Choose an interval long enough to contain several scrapes; a window that is shorter than or barely equal to the scrape interval can produce unstable or empty results.
A range selector by itself is usually not the value you want to display. Counter-oriented functions consume it to calculate a useful instant vector.
Calculate a per-second counter rate
Use rate() for the average per-second increase of a counter over a period:
rate(http_requests_total{job="prometheus"}[5m])
The metric name in this example is a counter: it is expected to increase over time, apart from resets when a process restarts. Apply rate() or increase() to counters, not to arbitrary gauges. The function’s five-minute window is part of the query’s meaning: a longer window smooths short spikes, while a shorter window responds faster but can be noisier.
Calculate the number added during a window
increase() expresses the counter growth over the selected interval:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
increase(http_requests_total{job="prometheus"}[1h])
Because counters can reset, these functions account for the reset behavior rather than treating a restart as a genuine negative workload change. Confirm the metric’s type and instrumentation before interpreting the result.
Aggregate without losing the dimension you need
Selectors often return one series per instance, status, route, or other label combination. Aggregation operators combine those series. The most useful form is usually sum by (...), which retains only the labels named in the parentheses.
Current request count by service
sum by (job) (http_requests_total)
This produces one series for each job, summing away other labels such as instance or status. If you need a fleet-wide total, omit the grouping labels:
sum(http_requests_total)
That total is meaningful only if summing the underlying series is appropriate. For counters, a current raw total is often less useful than a rate:
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchessum by (job) (rate(http_requests_total[5m]))
Here the five-minute rate is calculated per series first, then the rates are summed by job. Keeping the grouping label preserves the service-level dimension needed to identify which service is busy.
Choose aggregation labels deliberately
Before aggregating, ask which question the result must answer:
- Use
sum by (job)for a service-level total. - Use
sum by (instance)for a host or process view. - Keep
statuswhen success and error traffic must remain separate. - Drop high-cardinality dimensions such as an unbounded request ID unless the query specifically investigates them.
Aggregation changes cardinality. Removing a label can make a query manageable; retaining too many labels can return a series for every combination. Conversely, removing a label that explains the result can hide an important failure mode. Inspect the table output after each aggregation change.
Combine arithmetic, comparisons, and vector matching carefully
PromQL supports binary operators for arithmetic and comparisons, along with logical set-style operations. Arithmetic is useful for deriving rates and percentages, but combining vectors requires compatible label sets. Prometheus matches series according to their labels; an unmatched series may disappear, while an unintended many-to-many relationship can produce an unexpectedly large result or an invalid expression.
Free tools Windows power users keep installed
One-click scans. No signup required.
Compute an error percentage
This query calculates the share of requests whose status label begins with a five:
100 * sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
The regular expression is fully anchored, so 5.. matches a three-character value beginning with 5, such as 500 or 503. The numerator and denominator are both aggregated to one compatible total before division. If you group one side by job, group the other side the same way so the division still has a clear one-to-one match.
Rank #4
Understand vector matching before joining series
When two instant vectors appear in one binary expression, Prometheus matches their label sets. A common failure is to aggregate one operand by job while leaving the other at job, instance, and status. The labels no longer line up, so the result can omit data or behave differently from the intended calculation.
Make the dimensions explicit by aggregating both operands to the same labels, or use PromQL’s vector-matching modifiers only when you understand the cardinality they create. A many-to-one match can attach one reference series to several data series; careless matching can multiply work and obscure which labels came from which side.
Worked PromQL patterns
| Question | Expression | What to verify |
|---|---|---|
| Are targets reporting now? | up |
Check the returned job, instance, and value labels. |
| What is the current request counter by service? | sum by (job) (http_requests_total) |
Confirm that the metric is a counter and that job is present. |
| What is the request rate by service? | sum by (job) (rate(http_requests_total[5m])) |
Use a window containing several scrapes and inspect for missing series. |
| What percentage of requests are server errors? | 100 * sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) |
Ensure the status label uses three-digit values and both totals cover the same traffic. |
| What is non-idle CPU usage by instance? | 100 * (1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))) |
Interpret the result as a percentage and confirm the idle counter exists for each instance. |
| What was a counter’s value one hour earlier? | http_requests_total offset 1h |
offset shifts the evaluation time; it is not a second data source. |
These are teaching patterns, not universal metric names. Substitute the names and labels emitted by your own exporters and applications. If a pattern returns nothing, first query the base metric without functions or aggregation.
Instant queries versus range queries
An instant query evaluates an expression at one timestamp. If no timestamp is supplied, the server uses the current evaluation time. In the UI, this is the Table view. It is best for a current status, a single value for an alert decision, or checking the labels produced by an expression.
A range query evaluates the same expression repeatedly at equally spaced steps between a start and end time. In the UI, this is the Graph view. The expression itself still needs to produce a scalar or instant vector at each step; the API wraps those point-in-time results into a time series.
| Decision | Instant query | Range query |
|---|---|---|
| Evaluation | One timestamp | Many equally spaced timestamps |
| UI view | Table | Graph |
| Typical question | “What is the value now?” | “How did it change over this interval?” |
| API endpoint | /api/v1/query |
/api/v1/query_range |
| Required time inputs | Optional evaluation timestamp | start, end, and step |
A range query is not a replacement for a range selector. The selector, such as [5m], tells a function how much history to inspect at each evaluation step. The query range tells Prometheus which timestamps to evaluate across the larger display interval.
Query Prometheus through the HTTP API
External programs can fetch the result of a PromQL expression through Prometheus’s versioned HTTP API. The current stable API is under /api/v1.
Send an instant query
Use GET or POST on /api/v1/query. This shell example URL-encodes the expression:
Best Value
curl -G 'http://localhost:9090/api/v1/query'
--data-urlencode 'query=up{job="prometheus"}'
The server returns JSON on success. The response includes a status and a result object whose data identifies the result type and the returned series or scalar. Write scripts against the documented response structure rather than scraping the web UI.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Send a range query
Use /api/v1/query_range and provide the expression, start time, end time, and step:
curl -G 'http://localhost:9090/api/v1/query_range'
--data-urlencode 'query=sum(rate(http_requests_total[5m]))'
--data-urlencode 'start=2026-01-01T11:00:00Z'
--data-urlencode 'end=2026-01-01T12:00:00Z'
--data-urlencode 'step=60s'
The timestamps here are illustrative RFC3339 values. The API also accepts Unix timestamps. Choose a step that provides the resolution you need without requesting an unnecessarily large number of evaluations. A long interval with a very small step can generate a large response and consume substantial server resources.
Handle API failures explicitly
Do not treat an HTTP response as successful merely because the request reached port 9090. Prometheus documents status codes including:
- 400 for malformed parameters, such as an invalid time or missing required value.
- 422 when the expression is syntactically valid but cannot be executed.
- 503 when evaluation times out or is aborted.
Have automation check both the HTTP status and the JSON status field. Log the expression, time range, step, and server error message, while avoiding unbounded retries for a query that is inherently too expensive.
A reliable workflow for writing and automating queries
- Identify the question and metric type. Decide whether you need a current value, a trend, a counter rate, a total over a window, or a derived percentage. Verify whether the source metric is a counter or a gauge.
- Test the bare metric name in Table view. Record the actual labels and confirm that samples exist at the time you are evaluating.
- Add exact matchers first. Narrow by stable labels such as
job, environment, or service. Add negative or regular-expression matchers only when they express a real requirement. - Add a range selector for history-dependent functions. Start with a window such as
[5m], then adjust it to the scrape frequency and the stability you need. - Apply the function before aggregation when appropriate. For counters, calculate
rate()orincrease()per series, then sum those results across the desired dimension. - Aggregate to the labels needed by the question. Remove dimensions that create noise, but keep labels needed to identify a failing service, instance, or status.
- Inspect the table result again. Check the number of series, label sets, units, and unexpected missing values before graphing.
- Test historical behavior in Graph view. Look for restarts, gaps, resets, and changes in cardinality across the selected period.
- Move the verified expression to the API. Encode query parameters, use explicit RFC3339 or Unix times, set a sensible step, and handle 400, 422, and 503 responses.
Common problems and how to fix them
“No data” appears
- Query the metric name without labels to check whether the name is correct.
- Remove the newest matcher, then add matchers back one by one.
- Check that the selected time includes a scrape and that the target is still reporting.
- Confirm that the label exists on this metric; labels are not automatically shared by every metric from the same target.
The query returns far too many series
- Add an exact
job, service, environment, or instance matcher. - Use
sum by (...)to retain only the operational dimension you need. - Avoid broad regular expressions over high-cardinality labels.
- Inspect the table before sending the expression repeatedly from a dashboard or script.
A rate is empty or erratic
- Confirm the metric is a counter and that the range window contains multiple samples.
- Try a longer window if the scrape interval is long or samples are intermittent.
- Check for target restarts and counter resets in the graph.
- Do not apply counter functions to a gauge merely because the metric name ends in a familiar suffix.
An arithmetic expression drops series
- Compare the labels on both operands in Table view.
- Aggregate both sides to the same grouping labels before dividing or subtracting.
- Review vector-matching rules when one side has one series per service and the other has one per instance.
- Be especially cautious with many-to-one matches, which can increase the number of output series and the query cost.
The API request fails but the expression works in the UI
- URL-encode braces, quotes, brackets, and spaces in the query parameter.
- Use the correct endpoint:
/api/v1/queryfor an instant evaluation and/api/v1/query_rangefor start/end/step evaluation. - Check that
startandendare valid RFC3339 or Unix values and thatstepis supplied for a range query. - Inspect the JSON error and HTTP status rather than assuming a transport problem.
PromQL decisions that keep self-hosted monitoring usable
Self-hosted Prometheus makes it easy to add exporters and application labels, but every label combination can create another time series. Query design should therefore balance precision, meaning, and cost. A selector that is perfect for a one-time investigation may be unsuitable for a dashboard that refreshes every few seconds.
Use the smallest time window that answers the operational question while still providing enough samples for the function. Use a longer range only when smoothing or historical context is important. Keep aggregation close to the question: service owners generally need a service-level rate, while a host investigation may need the instance dimension. When comparing two expressions, make their label dimensions intentional before applying arithmetic.
Finally, treat the Table view as part of query development, not merely a display option. It exposes the actual result type, labels, values, and cardinality at one timestamp. Once those are correct, the Graph view can reveal behavior over time and the API can safely turn the expression into repeatable automation.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →

