Element-wise operations between vectors
PromQL can operate on two instant vectors element-wise. For example, to compute the percentage of free space per filesystem, divide available bytes by total size and multiply by 100:Label-matching rule (exact by default)
By default, PromQL only pairs two samples when their complete set of labels and values are identical. The matching process checks every label on the left sample and tries to find a sample on the right with the exact same label names and values.All labels on the two vectors must match exactly unless you use
on(...) or ignoring(...) to control which labels are used for matching.instance differs, these samples will not pair.
Controlling which labels are used for matching
Useon(...) to list the label names to match on, or ignoring(...) to exclude certain labels from the matching. This is vital when one metric has additional label dimensions that should not prevent matching.
Example: compute the percentage of 500 errors per HTTP method when error metrics include a code label, but request metrics do not.
Input metrics:
method:
- Ignore the
codelabel on the errors side:
- Or explicitly match on
method:
put (only in http_errors) and del (only in http_requests) will be dropped from the output.
You can list multiple labels in on(...):
Example: match on CPU but ignore mode
When metrics include different operational modes but you only want to match by CPU: vector1:on(cpu) or ignoring(mode) to match samples by cpu only.

Matching modes: one-to-one, many-to-one, one-to-many
- One-to-one (default): each element on the left matches at most one element on the right.
- Many-to-one / one-to-many: when multiple samples on one side match a single sample on the other side, you must explicitly allow this with
group_left()orgroup_right().
path and error vs. total requests per path.
Input:
http_errors entries for each path. Tell PromQL that the left-hand side may have multiple entries matching a single right-hand entry with group_left():
group_left() preserves the extra labels from the left-hand side (for example error) in the output.

group_right() when the right-hand side may have multiple matching samples per single left-hand sample (one-to-many in the opposite direction). The group_*() modifier may be used with or without a label list; providing a label list preserves those labels from the many side in the result.
Prometheus UI example: filesystem availability percentage
Each filesystem time series commonly includes labels likedevice, fstype, instance, job, and mountpoint. When the label sets align exactly between node_filesystem_avail_bytes and node_filesystem_size_bytes, dividing them yields the percentage available for that timeseries:

error label), the division returns no results unless you control matching with on(...), ignoring(...), and—if multiple matches occur—group_left() or group_right().

Example: HTTP errors vs. HTTP requests totals
Whenhttp_errors_total includes an error label and http_requests_total does not:
error from matching:
http_errors_total samples (different error values) match a single http_requests_total sample, use group_left() to explicitly allow many-to-one matching and retain the error label in results:

Matching modes at a glance
Note: In the table,
A and B represent vectors; any label selectors like {path="/cats"} should be written as PromQL expressions in queries.
Practical tips and links
- Always inspect the label sets of the two vectors (
label_join,label_replace, or the Prometheus UI) before combining them to avoid silent drops or errors. - Use
on(...)to restrict matching to specific key labels, andignoring(...)to exclude irrelevant labels. - When allowing multiple matches, choose
group_left()orgroup_right()according to which side holds the extra label dimensions you want to preserve. - To explicitly keep only select labels from the many side, supply them to
group_left(<labels...>)orgroup_right(<labels...>).
- PromQL defaults to strict one-to-one label matching.
- Use
on(...)/ignoring(...)to control which labels are considered for matching. - Use
group_left()/group_right()to explicitly allow many-to-one or one-to-many matches and to preserve labels from the many side when needed.