Skip to content
Open
Changes from 3 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b49a0e1
Add info function blog post
aknuds1 Nov 14, 2025
102f34d
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Nov 17, 2025
933a579
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Nov 17, 2025
e0a6e06
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Nov 27, 2025
3fb7592
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Nov 27, 2025
b7f466e
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Nov 27, 2025
6bf6f39
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Nov 27, 2025
8f33dea
Merge remote-tracking branch 'origin/main' into arve/info-blog-post
aknuds1 Nov 27, 2025
220ade1
Apply reviewer feedback
aknuds1 Nov 27, 2025
729a755
Apply reviewer feedback
aknuds1 Nov 27, 2025
4358dfc
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Nov 27, 2025
2f68dcb
Apply reviewer feedback
aknuds1 Nov 27, 2025
c6df22a
Apply reviewer feedback
aknuds1 Nov 27, 2025
39a1864
Apply reviewer feedback
aknuds1 Nov 27, 2025
151a16e
Apply reviewer feedback
aknuds1 Nov 27, 2025
d8c4afb
Apply reviewer feedback
aknuds1 Nov 27, 2025
61033ae
Apply reviewer feedback
aknuds1 Nov 27, 2025
a083bca
Apply reviewer feedback
aknuds1 Nov 27, 2025
aa82bae
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Dec 2, 2025
f8b572d
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Dec 2, 2025
893356a
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Dec 2, 2025
6b2367c
Update blog/posts/2025-11-14-introducing-info-function.md
aknuds1 Dec 2, 2025
61621b6
Apply reviewer feedback
aknuds1 Dec 2, 2025
60d5707
Merge remote-tracking branch 'origin/main' into arve/info-blog-post
aknuds1 Dec 2, 2025
386253e
Apply reviewer feedback
aknuds1 Dec 2, 2025
018760b
Tweak language
aknuds1 Dec 2, 2025
823a03d
Move feedback to its own section
aknuds1 Dec 3, 2025
41da4ff
Move Giving Feedback section before Conclusion
aknuds1 Dec 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
298 changes: 298 additions & 0 deletions blog/posts/2025-11-14-introducing-info-function.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
---
title: Introducing the Experimental info() Function
created_at: 2025-11-14
kind: article
author_name: Arve Knudsen
---

Enriching metrics with metadata labels can be surprisingly tricky in Prometheus, even if you're a PromQL wiz!
Traditionally, complex PromQL join syntax is required in Prometheus to add even basic information like Kubernetes cluster names or cloud provider regions to queries.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds like it's just a problem of syntax. This blog post might be an opportunity to debunk this naive assumption that is in everyone's head.
It could also be a good segue into the parts of the info function that still need to be finished before it can unleash its true power.

To reiterate the reasons for the complexity of the join query:

  • You have to specify on which labels to join (segue into what "identifying labels" means, see @ywwg's comment, and that we want to store this information in the future).
  • You have to specify the info metric to join with (segue into storing the type information in the future to know what info metrics exist).
  • You have to specify which "data labels" to copy over from the info metric.

Of course, you cannot explain all of this in the opening paragraph, but maybe a bit of it, something like:

Suggested change
Traditionally, complex PromQL join syntax is required in Prometheus to add even basic information like Kubernetes cluster names or cloud provider regions to queries.
The PromQL join query traditionally used for this is inherently quite complex because it has to specify the labels to join on, the info metric to join with, and the labels to enrich with.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PTAL.

The new, still experimental `info()` function, promises a simpler way, making label enrichment as simple as wrapping your query in a single function call.

In Prometheus 3.0, we introduced the [`info()`](https://prometheus.io/docs/prometheus/latest/querying/functions/#info) function, a powerful new way to enrich your time series with labels from info metrics.
`info` doesn't only offer a simpler syntax however.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I don't think the fundamental nature of the problem is syntactical.

info is simpler because you do not have to specify the identifying labels, you do not have to specify the info metric to join with, and if you just want to enrich with all data labels, you do not even have to specify the data labels you want to enrich with.

I think each of the three features is more important (both in practical terms and as a key insight how info works and why it is useful) than the next one (the "churn problem"), among others because the churn problem only occurs with broken staleness handling (which could be fixed in OTLP ingestion), and it should actually never occur if OTel folks just used resource attributes as they are meant to be used. (Of course, we don't need to explain those subtleties here, I just want to put things into perspective.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised, PTAL.

It also solves a subtle yet critical problem that has plagued join queries for years: The "churn problem" that causes queries to fail when "non-identifying" info metric labels change.
In practice, "identifying labels" refers to those labels that the join is performed on.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should expand a section laying out what "identifying" really means, compared to "data labels" or "nonidentifying labels", referencing the otel data model (which also uses the word "descriptive"!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to write a section and make a PR to my branch or something? Maybe the easiest.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, can do


Whether you're working with OpenTelemetry resource attributes, Kubernetes labels, or any other metadata, the `info()` function makes your PromQL queries cleaner, more reliable, and easier to understand.

<!-- more -->

## The Problem: Complex Joins and The Churn Problem

Let us start by looking at what we have had to do until now.
Imagine you're monitoring HTTP request durations via OpenTelemetry and want to break them down by Kubernetes cluster.
Your metrics have `job` and `instance` labels, but the cluster name lives in a separate `target_info` metric, as the `k8s_cluster_name` label.
Here's what the traditional approach looks like:

```promql
sum by (k8s_cluster_name, http_status_code) (
rate(http_server_request_duration_seconds_count[2m])
* on (job, instance) group_left (k8s_cluster_name)
target_info
)
```

While this works, there are several issues:

**1. Complexity:** You need to know:
- Which info metric contains your labels (`target_info`)
- Which labels are the "identifying" labels to join on (`job`, `instance`)
- Which data labels you want to add (`k8s_cluster_name`)
- The proper PromQL join syntax (`on`, `group_left`)

This requires expert-level PromQL knowledge and makes queries harder to read and maintain.

**2. The Churn Problem (The Critical Issue):**

Here's the subtle but serious problem: What happens when a Kubernetes pod gets recreated?
The `k8s_pod_name` label in `target_info` changes, and Prometheus sees this as a completely new time series.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that in this situation, also the instance label will change (and has to change according to OTel conventions), so this problem shouldn't occur.

Maybe we can still keep using this example, but we should then also mention that this is a broken setup (where instance doesn't change upon pod recreation).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised, PTAL.


If the old `target_info` series isn't properly marked as stale immediately, both the old and new series can exist simultaneously for up to 5 minutes (the default lookback delta).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe don't phrase this as an "if". It will never be marked properly as stale because of the way OTLP ingestion works. So on the one hand, we can clearly say that the staleness handling doesn't work right now, but we could also mention that this is an issue that could be fixed in the OTLP ingestion layer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised, PTAL.

During this overlap period, your join query finds **two distinct matching `target_info` time series** and fails with a "many-to-many matching" error.

This could in practice mean your dashboards break and your alerts stop firing when infrastructure changes are happening, perhaps precisely when you would need visibility the most.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something is missing here. A headline like "The Solution in its simplest form" or something?

Currently, this appears as just another paragraph in the section describing the 2nd part of the problem…

Copy link
Contributor Author

@aknuds1 aknuds1 Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. On reviewing the section, I realized that a sub-section was missing. I added it, PTAL.

## The Solution: Simple, Reliable Label Enrichment

The `info()` function solves both problems at once.
Here's the same query using `info()`:

```promql
sum by (k8s_cluster_name, http_status_code) (
info(
rate(http_server_request_duration_seconds_count[2m]),
{k8s_cluster_name=~".+"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we should better start with the easiest use case first, as this is about showcasing the simplicity. So let's leave out this line (it is also the one "weird" part of the info function, a new type of function parameter, using selector syntax without being a real selector).

It will promote all data labels, but that's not a problem because we aggregate them away in the sum anyway. (You can explain that later.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PTAL.

)
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
sum by (k8s_cluster_name, http_status_code) (
info(
rate(http_server_request_duration_seconds_count[2m]),
{k8s_cluster_name=~".+"}
)
)
sum by (k8s_cluster_name, http_status_code) (
info(rate(http_server_request_duration_seconds_count[2m]))
)

As per my other comment.

Maybe then follow up with the detail that this uses all data labels, then explain that it doesn't matter because we are aggregating them away in the sum, and then introduce the selector to select just one label, in cases where that is needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised, PTAL.

```

Much more comprehensible, no?
The real magic happens under the hood though: **`info()` automatically selects the time series with the latest sample**, eliminating churn-related join failures entirely.

### Basic Syntax
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know Patrick ran into issues where info() had to be put in very specific places, especially when a rate function was involved. I think his intuition was to "wrap the metric name in info()" but that doesn't work when there's a rate function? So I think we should have an aside with some advice on how to know where the info function will need to go.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree in general, but the rationale is not that info is special or needlessly complicated here, but the opposite: info is just a normal function. Nothing new here. You place it where you place any other function that receives an instant vector. (You could call that "very specific places". I would call it "just the normal expected places".) For example, label_replace is placed at exactly the same places where you would use info. (Buth functions not only take an instant vector as an argument, they also share the property that they just manipulate labels, not values. All perfectly normal and expected – I might even use the infamous word "intuitive" for that.)

Patrick's issue has to do with PromQL in general, not info in particular. Obviously, the intuition of somebody not familiar with PromQL is very different from the intuition of somebody who knows PromQL. Catering for the one might very well be counterproductive for the other.

So we should argue here that info is just a normal function acting on any instant vector, not any new concept like a "decorator" or something.


```promql
info(v instant-vector, [data-label-selector instant-vector])
```

- **`v`**: The instant vector to enrich with metadata labels
- **`data-label-selector`** (optional): Label matchers in curly braces to filter which labels to include

If you omit the second parameter, `info()` adds **all** data labels from `target_info`:

```promql
info(rate(http_server_request_duration_seconds_count[2m]))
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As said, I would frame this is the primary mode of using info. See above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised, PTAL.


### Selecting Different Info Metrics

By default, `info()` uses the `target_info` metric.
However, you can select different info metrics (like `build_info`, `node_uname_info`, or `kube_pod_labels`) by including a `__name__` matcher in the data-label-selector:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kube_pod_labels doesn't work because it will have the job and instance labels from KSM (which we would need to ignore in the join) and requires joining on namespace and pod, see comment below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed it, PTAL.


```promql
# Use build_info instead of target_info
info(up, {__name__="build_info"})

# Use multiple info metrics (combines labels from both)
info(up, {__name__=~"(target|build)_info"})

# Select build_info and only include the version label
info(up, {__name__="build_info", version=~".+"})
```

**Note:** The current implementation always uses `job` and `instance` as the identifying labels for joining, regardless of which info metric you select.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also note that the future intention is that PromQL "knows" what metrics in the TSDB are info metrics and automatically uses all of them, unless the selection is explicitly restricted by a name matcher like the above.

General question (not part of the review): Why didn't we make it possible to just write info(up, build_info) or info(up, build_info{version=~".+"})?
Maybe info(up, {"build_info"}) or info(up, {"build_info", version=~".+"}) works already?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised, PTAL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why didn't we make it possible to just write info(up, build_info) or info(up, build_info{version=~".+"})?

I don't remember it being considered :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I vaguely remember that there was a reason, but I don't remember the reason itself. 😬

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be that it's difficult to support the syntax technically. Maybe with the current state of the implementation, these ideas could be revisited?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I would love that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"current implementation" implies that this may change, do we have any plans to? Maybe we can call out that we are looking for feedback on this point

Copy link
Contributor Author

@aknuds1 aknuds1 Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"current implementation" implies that this may change, do we have any plans to?

Yes the plan is relatively clear, the last sentence of the same paragraph already explains how it's supposed to work in the future. I don't think we need to solicit feedback, since we know how it's supposed to work on top of persisted metadata.

This works well for most standard info metrics but may have limitations with custom info metrics that use different identifying labels.

## Real-World Use Cases

### OpenTelemetry Integration

The primary driver for the `info()` function is [OpenTelemetry](https://prometheus.io/blog/2024/03/14/commitment-to-opentelemetry/) (OTel) integration.
When using Prometheus as an OTel backend, resource attributes (metadata about the metrics producer) are automatically converted to the `target_info` metric:

- `service.instance.id` → `instance` label
- `service.name` → `job` label
- `service.namespace` → prefixed to `job` (i.e., `<namespace>/<service.name>`)
- All other resource attributes → data labels on `target_info`

This means that, so long as at least either the `service.instance.id` or the `service.name` resource attribute is included, every OTel metric you send to Prometheus over OTLP can be enriched with resource attributes using `info()`:

```promql
# Add all OTel resource attributes
info(rate(http_server_request_duration_seconds_sum[5m]))

# Add only specific attributes
info(
rate(http_server_request_duration_seconds_sum[5m]),
{k8s_cluster_name=~".+", k8s_namespace_name=~".+", k8s_pod_name=~".+"}
)
```

### Kubernetes Metadata

Enrich your metrics with Kubernetes-specific information:

```promql
# Add cluster and namespace information to request rates
info(
sum by (job, http_status_code) (
rate(http_server_request_duration_seconds_count[2m])
),
{k8s_cluster_name=~".+", k8s_namespace_name=~".+"}
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this different from the above?

Maybe we can add an example here that is not tailored to OTel/target_info? Maybe something using build_info.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised, PTAL.

```

### Cloud Provider Metadata

Add cloud provider information to understand costs and performance by region:

```promql
# Enrich with AWS/GCP/Azure region and availability zone
info(
rate(cloud_storage_request_count[5m]),
{cloud_provider=~".+", cloud_region=~".+", cloud_availability_zone=~".+"}
)
```

## Before and After: Side-by-Side Comparison

Let's see how the `info()` function simplifies real queries:

### Example 1: Basic Label Enrichment
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should include an example where you want to use a lot of resource attributes (because that's very long in the join query, but you just use the default behavior of info). Just promoting a single RA is kind-of the worst case for info and the best case for the traditional join query, so we shouldn't list it is the 1st example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I turned example 1 into such an example, PTAL.


**Traditional approach:**
```promql
rate(http_server_request_duration_seconds_count[2m])
* on (job, instance) group_left (k8s_cluster_name)
target_info
```

**With info():**
```promql
info(
rate(http_server_request_duration_seconds_count[2m]),
{k8s_cluster_name=~".+"}
)
```

### Example 2: Aggregation with Multiple Labels

**Traditional approach:**
```promql
sum by (k8s_cluster_name, k8s_namespace_name, http_status_code) (
rate(http_server_request_duration_seconds_count[2m])
* on (job, instance) group_left (k8s_cluster_name, k8s_namespace_name)
target_info
)
```

**With info():**
```promql
sum by (k8s_cluster_name, k8s_namespace_name, http_status_code) (
info(
rate(http_server_request_duration_seconds_count[2m]),
{k8s_cluster_name=~".+", k8s_namespace_name=~".+"}
)
)
```

The intent is much clearer with `info`: We're enriching `http_server_request_duration_seconds_count` with cluster and namespace information, then aggregating by those labels and `http_status_code`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also add an Example 3 with filtering for label values. That's also possible with the join query, but makes things even more verbose, while info does it in a very natural way. Another strength of info we can and should showcase here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this as example 2 (dropped the original one), PTAL.


## Technical Benefits

Beyond cleaner syntax, the `info()` function provides several technical advantages:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not just syntax, as said. info is utilizing information that has otherwise to be provided by the user. Sorry for hammering this in so much, but I think this is very crucial to understand why info is so cool (and also what is still missing in its implementation).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised, PTAL.


### 1. Automatic Churn Handling

As previously mentioned, `info()` automatically picks the matching info time series with the latest sample when multiple versions exist.
This eliminates the "many-to-many matching" errors that plague traditional join queries during churn.

**How it works:** When non-identifying info metric labels change (e.g., a pod is re-created), there's a brief period where both old and new series might exist.
The `info()` function simply selects whichever has the most recent sample, ensuring your queries keep working.

### 2. Better Performance

The `info()` function is more efficient than traditional joins:
- Only selects matching info series
- Avoids unnecessary label matching operations
- Optimized query execution path
Comment on lines +241 to +244
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know some people were suspicious about the performance of the target_info concept ... Do we have numbers comparing the performance of label promotion vs info() joining? If it's small enough, that may help discourage people from promoting everything by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know about perf comparisons versus label promotion. I just know there's an obvious performance benefit over join queries, due to being able to filter what to select on the RHS :)


## Getting Started

The `info()` function is experimental and must be enabled via a feature flag:

```bash
prometheus --enable-feature=promql-experimental-functions
```

Once enabled, you can start using it immediately.
Here are some simple examples to try:

```promql
# Basic usage - add all target_info labels
info(up)

# Selective enrichment - add only cluster name
info(up, {k8s_cluster_name=~".+"})

# In a real query
info(
rate(http_server_request_duration_seconds_count[5m]),
{k8s_cluster_name=~".+"}
)

# With aggregation
sum by (k8s_cluster_name) (
info(up, {k8s_cluster_name=~".+"})
)
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if there is value to repeat examples already given above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed them, PTAL.


## Current Limitations and Future Plans

The current implementation is an **MVP (Minimum Viable Product)** designed to validate the approach and gather user feedback.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a link to directly file an issue? "If you experience any issues with info() please report them here" etc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, PTAL.

It has some intentional limitations:

### Current Constraints

1. **Default info metric:** Only considers `target_info` by default
- Workaround: You can use `__name__` matchers like `{__name__=~"(target|build)_info"}` in the data-label-selector, though this still assumes `job` and `instance` as identifying labels

2. **Fixed identifying labels:** Always assumes `job` and `instance` are the identifying labels for joining
- This works for most use cases but may not be suitable for all scenarios
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this over-promises. There are common use cases already where this doesn't work. You even dropped kube_pod_labels above. We should clearly say that this is a real problem but also that we want to solve this in the future (by storing the information which labels are identifying).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised, PTAL.


### Future Development

These limitations are meant to be temporary.
The experimental status allows us to:
- Gather real-world usage feedback
- Understand which use cases matter the most
- Iterate on the design before committing to a final API

A future version of the `info()` function should:
- Support all info metrics (not just `target_info`)
- Dynamically determine identifying labels based on the info metric's structure
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not so much dynamic, but it's about (statically) storing the information what labels are identifying.

Note for future implementations (not related to the review, just happened to come to my mind while doing this review): For something like kube_pod_labels, we'll have the actual identifying labels (namespace, pod), then we'll have the data labels (in this case the actual pod labels), but when these metrics are ingested from KSM, we will also get a job and instance label attached (and whatever other target labels are configured). The future perfect version of info probably should just join on namespace and pod and only add the pod labels, but completely ignore job and instance and possibly other target labels (i.e. don't join on them, but also don't add them to the result either). Devil is in the detail here…

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised, PTAL.


**Important:** Because this is an experimental feature, the behavior may change in future Prometheus versions, or the function could potentially be removed from PromQL entirely based on user feedback.

## Conclusion

The experimental `info()` function represents a significant step forward in making PromQL more accessible and reliable.
By simplifying metadata label enrichment and automatically handling the churn problem, it removes two major pain points for Prometheus users, especially those adopting OpenTelemetry.

We encourage you to try the `info()` function and share your feedback:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

link again

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, PTAL.

- What use cases does it solve for you?
- What additional functionality would you like to see?
- How could the API be improved?
- Do you see improved performance?

Your feedback will directly shape the future of this feature and help us determine whether it should become a permanent part of PromQL.

To learn more:
- [PromQL functions documentation](https://prometheus.io/docs/prometheus/latest/querying/functions/#info)
- [OpenTelemetry guide (includes detailed info() usage)](https://prometheus.io/docs/guides/opentelemetry/)
- [Feature proposal](https://github.com/prometheus/proposals/blob/main/proposals/0037-native-support-for-info-metrics-metadata.md)

Please feel welcome to share your thoughts with the Prometheus community on [GitHub Discussions](https://github.com/prometheus/prometheus/discussions) or get in touch with us on the [CNCF Slack #prometheus channel](https://cloud-native.slack.com/).

Happy querying!