Skip to content

model/labels: Add case-insensitive prefix matching optimization#18540

Merged
bboreham merged 2 commits into
prometheus:mainfrom
chencs:case-insensitive-prefix-matching
Jun 2, 2026
Merged

model/labels: Add case-insensitive prefix matching optimization#18540
bboreham merged 2 commits into
prometheus:mainfrom
chencs:case-insensitive-prefix-matching

Conversation

@chencs

@chencs chencs commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

This change adds support for case-insensitive prefix matching, with the goal of especially improving performance when evaluating long case-insensitive regexes, without degrading performance particularly in other cases.

Note the benchmark results for report.scheduled.job_runscheduledreports vs (?i)report.scheduled.job_runscheduledreports. The case-insensitive regular expression takes ~twice as long to evaulate in the original case, and introducing this change brings them much closer together in performance.

BenchmarkFastRegexMatcher results
% benchstat original.txt case_insensitive_prefix.txt   
goos: darwin
goarch: arm64
pkg: github.com/prometheus/prometheus/model/labels
cpu: Apple M2 Pro
                                                        │ original.txt  │      case_insensitive_prefix.txt      │
                                                        │    sec/op     │    sec/op      vs base                │
FastRegexMatcher/#00-10                                    54.71n ±  0%    56.28n ±  4%   +2.88% (p=0.000 n=10)
FastRegexMatcher/foo-10                                    57.67n ±  0%    59.57n ±  7%   +3.31% (p=0.000 n=10)
FastRegexMatcher/^foo-10                                   66.55n ±  0%    67.36n ±  3%   +1.21% (p=0.000 n=10)
FastRegexMatcher/(foo|bar)-10                              81.71n ±  1%    82.45n ±  2%   +0.91% (p=0.000 n=10)
FastRegexMatcher/foo.*-10                                  95.87n ±  1%    98.80n ±  2%   +3.05% (p=0.001 n=10)
FastRegexMatcher/.*foo-10                                  112.0n ±  0%    113.7n ±  2%        ~ (p=0.100 n=10)
FastRegexMatcher/^.*foo$-10                                111.9n ±  1%    113.4n ±  2%        ~ (p=0.159 n=10)
FastRegexMatcher/^.+foo$-10                                112.5n ±  1%    112.4n ± 10%        ~ (p=0.957 n=10)
FastRegexMatcher/.?-10                                     78.31n ±  0%    78.85n ±  3%   +0.69% (p=0.000 n=10)
FastRegexMatcher/.*-10                                     53.75n ±  0%    54.69n ±  2%   +1.75% (p=0.000 n=10)
FastRegexMatcher/.+-10                                     56.03n ±  0%    57.16n ±  8%   +2.01% (p=0.002 n=10)
FastRegexMatcher/foo.+-10                                  96.27n ±  0%    97.41n ±  1%   +1.18% (p=0.000 n=10)
FastRegexMatcher/.+foo-10                                  113.4n ±  1%    111.8n ±  7%        ~ (p=0.137 n=10)
FastRegexMatcher/foo_.+-10                                 87.00n ±  0%    88.52n ±  2%   +1.74% (p=0.000 n=10)
FastRegexMatcher/foo_.*-10                                 87.03n ±  0%    88.17n ±  0%   +1.32% (p=0.000 n=10)
FastRegexMatcher/.*foo.*-10                                172.8n ±  0%    169.1n ±  1%   -2.11% (p=0.000 n=10)
FastRegexMatcher/.+foo.+-10                                205.2n ±  3%    201.1n ±  7%        ~ (p=0.105 n=10)
FastRegexMatcher/.*foo.*|-10                               244.3n ±  1%    246.2n ±  1%   +0.80% (p=0.000 n=10)
FastRegexMatcher/.*foo.*|bar.*-10                          281.9n ±  0%    287.1n ±  5%   +1.84% (p=0.000 n=10)
FastRegexMatcher/foo.*|.*bar.*-10                          280.2n ±  0%    284.3n ±  3%   +1.46% (p=0.000 n=10)
FastRegexMatcher/.*foo.*|.*bar.*-10                        297.3n ±  0%    298.3n ±  2%   +0.34% (p=0.030 n=10)
FastRegexMatcher/.*foo.*bar.*|.*hello.*-10                 13.77µ ±  0%    13.79µ ±  1%        ~ (p=0.516 n=10)
FastRegexMatcher/.*foo.*|.*bar.*|.*hello.*-10              486.6n ±  8%    490.9n ±  3%        ~ (p=0.564 n=10)
FastRegexMatcher/.+.*foo.*|.*bar.*-10                      16.06µ ±  1%    16.19µ ±  1%   +0.81% (p=0.009 n=10)
FastRegexMatcher/(?s:.*)-10                                53.60n ±  1%    54.44n ±  0%   +1.56% (p=0.000 n=10)
FastRegexMatcher/(?s:.+)-10                                56.15n ±  1%    56.81n ±  5%        ~ (p=0.393 n=10)
FastRegexMatcher/(?s:^.*foo$)-10                           113.5n ±  1%    111.6n ±  1%   -1.67% (p=0.001 n=10)
FastRegexMatcher/(?i:foo)-10                               81.41n ±  0%    82.18n ±  2%   +0.95% (p=0.001 n=10)
FastRegexMatcher/(?i:(foo|bar))-10                         169.6n ±  1%    170.4n ± 11%   +0.44% (p=0.019 n=10)
FastRegexMatcher/(?i:(foo1|foo2|bar))-10                   299.0n ±  1%    302.8n ±  2%   +1.25% (p=0.000 n=10)
FastRegexMatcher/^(?i:foo|oo)|(bar)$-10                    743.0n ± 14%    743.1n ±  6%        ~ (p=0.529 n=10)
FastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10       632.8n ±  4%    612.1n ±  5%   -3.26% (p=0.034 n=10)
FastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10            469.5n ±  9%    462.4n ±  1%   -1.50% (p=0.007 n=10)
FastRegexMatcher/^$-10                                     54.77n ±  2%    54.93n ±  1%        ~ (p=0.306 n=10)
FastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10        173.3n ±  0%    174.2n ±  6%        ~ (p=0.066 n=10)
FastRegexMatcher/10\.0\.(1|2)\.+-10                        87.20n ±  1%    87.57n ±  0%   +0.42% (p=0.029 n=10)
FastRegexMatcher/10\.0\.(1|2).+-10                         87.53n ±  3%    88.56n ±  3%   +1.17% (p=0.015 n=10)
FastRegexMatcher/((fo(bar))|.+foo)-10                      211.9n ±  0%    205.5n ±  2%   -3.04% (p=0.001 n=10)
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10       186.8n ± 15%    179.7n ± 10%        ~ (p=0.143 n=10)
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10       188.8n ±  9%    184.2n ± 11%        ~ (p=0.616 n=10)
FastRegexMatcher/.*zQPbMkNO.*|.*NNSPdvMi.*|.*iWuu-10       11.86µ ±  1%    11.89µ ±  4%        ~ (p=0.143 n=10)
FastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10       621.4n ±  4%    610.2n ±  2%        ~ (p=0.137 n=10)
FastRegexMatcher/(?i:(AAAAAAAAAAAAAAAAAAAAAAAA|BB-10       374.6n ±  0%    383.8n ±  8%   +2.47% (p=0.045 n=10)
FastRegexMatcher/(?i:(zQPbMkNO.*|NNSPdvMi.*|iWuuS-10       269.5n ±  0%    269.4n ±  1%        ~ (p=0.809 n=10)
FastRegexMatcher/(?i:(zQPbMkNO.*|NNSPdvMi.*|iWuuS#01-10    445.2n ±  1%    452.0n ±  2%   +1.52% (p=0.003 n=10)
FastRegexMatcher/(?i:(.*zQPbMkNO|.*NNSPdvMi|.*iWu-10       7.513µ ±  1%    7.544µ ±  3%   +0.41% (p=0.030 n=10)
FastRegexMatcher/fo.?-10                                   97.56n ±  0%    99.16n ±  4%   +1.64% (p=0.000 n=10)
FastRegexMatcher/foo.?-10                                  97.60n ±  0%   101.75n ±  4%   +4.25% (p=0.000 n=10)
FastRegexMatcher/f.?o-10                                   81.08n ±  1%    81.95n ±  1%   +1.09% (p=0.043 n=10)
FastRegexMatcher/.*foo.?-10                                202.5n ±  0%    221.0n ± 18%   +9.16% (p=0.021 n=10)
FastRegexMatcher/.?foo.+-10                                196.5n ±  0%    198.6n ±  3%        ~ (p=0.313 n=10)
FastRegexMatcher/foo.?|bar-10                              159.1n ±  4%    154.8n ±  1%   -2.64% (p=0.000 n=10)
FastRegexMatcher/ſſs-10                                    57.97n ±  0%    58.80n ±  3%   +1.44% (p=0.000 n=10)
FastRegexMatcher/.*-.*-.*-.*-.*-10                         200.3n ±  1%    186.8n ±  4%   -6.76% (p=0.000 n=10)
FastRegexMatcher/.+-.*-.*-.*-.+-10                         199.6n ±  1%    184.8n ±  4%   -7.39% (p=0.000 n=10)
FastRegexMatcher/-.*-.*-.*-.*-10                           98.13n ±  1%   102.85n ±  9%   +4.81% (p=0.023 n=10)
FastRegexMatcher/.*-.*-.*-.*--10                           115.1n ±  0%    122.2n ± 21%   +6.13% (p=0.004 n=10)
FastRegexMatcher/(.+)-(.+)-(.+)-(.+)-(.+)-10               199.5n ±  2%    187.7n ± 11%        ~ (p=0.118 n=10)
FastRegexMatcher/((.*))(?i:f)((.*))o((.*))o((.*))-10       4.335µ ±  0%    4.572µ ± 23%   +5.47% (p=0.000 n=10)
FastRegexMatcher/((.*))f((.*))(?i:o)((.*))o((.*))-10       3.548µ ±  0%    3.694µ ± 12%   +4.11% (p=0.000 n=10)
FastRegexMatcher/(.*0.*)-10                                131.0n ±  1%    117.0n ±  1%  -10.68% (p=0.000 n=10)
FastRegexMatcher/(?i).*foo.*-10                            7.654µ ±  0%    7.732µ ±  2%   +1.01% (p=0.003 n=10)
FastRegexMatcher/(?i)report.scheduled.job_runsche-10      168.85n ±  0%    78.73n ±  2%  -53.37% (p=0.000 n=10)
FastRegexMatcher/report.scheduled.job_runschedule-10       87.39n ±  0%    87.81n ±  1%   +0.49% (p=0.003 n=10)
FastRegexMatcher/(?i).*zQPbMkNO.*|.*NNSPdvMi.*|.*-10       1.154m ±  0%    1.155m ±  5%        ~ (p=0.529 n=10)
FastRegexMatcher/(?i).*/label/.*|.*/labels.*|.*/s-10       19.23µ ±  1%    19.18µ ±  4%        ~ (p=0.271 n=10)
FastRegexMatcher/.*/label/.*|.*/labels.*|.*/serie-10       386.8n ±  5%    375.3n ±  3%        ~ (p=0.109 n=10)
geomean                                                    273.9n          271.6n         -0.84%

Which issue(s) does the PR fix:

Release notes for end users (ALL commits must be considered).

Reviewers should verify clarity and quality.

NONE

@bboreham

Copy link
Copy Markdown
Member

Would it be better to remove FastRegexMatcher.prefix and rely on literalPrefixSensitiveStringMatcher ?
(and then your change is to extend that to literalPrefixInsensitiveStringMatcher )

@chencs chencs force-pushed the case-insensitive-prefix-matching branch from 3a24433 to f0bdb9b Compare April 20, 2026 18:20
@chencs

chencs commented Apr 20, 2026

Copy link
Copy Markdown
Contributor Author

Would it be better to remove FastRegexMatcher.prefix and rely on literalPrefixSensitiveStringMatcher ?
(and then your change is to extend that to literalPrefixInsensitiveStringMatcher )

Good question! I'll explore that later this week.

@chencs

chencs commented Apr 23, 2026

Copy link
Copy Markdown
Contributor Author

I don't think we can, at least not without making changes I'm significantly less confident about. prefix is a fast path for specifically cases where the top-level regex has a prefix, but the logic in stringMatcherFromRegexpInternal has to be generalizable to any subexpression, so in cases where we would have a valid prefix but can't satisfy left == nil && len(matches) == 1, we end up with suboptimal matchers for cases that previously benefited from using prefix to filter values out fast.

For example, the 10\.0\.(1|2) test cases which expand out to 10.0.1 and 10.0.2 would previously get that 10.0. prefix, but now don't because there are >1 matches. Similarly, any matcher with a wildcard in the middle of a concat will also exit without creating a matcher.

BenchmarkFastRegexMatcher results

The benchmark results for no_prefix_in_struct.go involve the same logic as is in this PR, just without looking at prefix in compileMatchStringFunction.

% benchstat original.txt no_prefix_in_struct.txt
goos: darwin
goarch: arm64
pkg: github.com/prometheus/prometheus/model/labels
cpu: Apple M2 Pro
                                                        │ original.txt │         no_prefix_in_struct.txt          │
                                                        │    sec/op    │    sec/op      vs base                   │
FastRegexMatcher/#00-10                                   54.71n ±  0%    54.70n ±  0%         ~ (p=0.971 n=10)
FastRegexMatcher/foo-10                                   57.67n ±  0%    57.15n ±  2%         ~ (p=0.436 n=10)
FastRegexMatcher/^foo-10                                  66.55n ±  0%    67.27n ±  1%    +1.07% (p=0.000 n=10)
FastRegexMatcher/(foo|bar)-10                             81.71n ±  1%    82.27n ±  1%    +0.67% (p=0.035 n=10)
FastRegexMatcher/foo.*-10                                 95.87n ±  1%    90.19n ±  1%    -5.92% (p=0.000 n=10)
FastRegexMatcher/.*foo-10                                 112.0n ±  0%    108.0n ±  5%         ~ (p=0.092 n=10)
FastRegexMatcher/^.*foo$-10                               111.9n ±  1%    108.5n ±  5%    -3.04% (p=0.022 n=10)
FastRegexMatcher/^.+foo$-10                               112.5n ±  1%    113.3n ±  5%         ~ (p=0.516 n=10)
FastRegexMatcher/.?-10                                    78.31n ±  0%    78.93n ±  4%    +0.79% (p=0.008 n=10)
FastRegexMatcher/.*-10                                    53.75n ±  0%    54.88n ±  4%    +2.11% (p=0.001 n=10)
FastRegexMatcher/.+-10                                    56.03n ±  0%    56.47n ±  1%    +0.79% (p=0.000 n=10)
FastRegexMatcher/foo.+-10                                 96.27n ±  0%    90.30n ±  1%    -6.20% (p=0.000 n=10)
FastRegexMatcher/.+foo-10                                 113.4n ±  1%    108.5n ±  1%    -4.37% (p=0.000 n=10)
FastRegexMatcher/foo_.+-10                                87.00n ±  0%    82.41n ±  6%    -5.28% (p=0.017 n=10)
FastRegexMatcher/foo_.*-10                                87.03n ±  0%    83.58n ±  5%    -3.96% (p=0.022 n=10)
FastRegexMatcher/.*foo.*-10                               172.8n ±  0%    163.2n ±  2%    -5.56% (p=0.000 n=10)
FastRegexMatcher/.+foo.+-10                               205.2n ±  3%    193.5n ±  3%    -5.70% (p=0.001 n=10)
FastRegexMatcher/.*foo.*|-10                              244.3n ±  1%    257.9n ±  1%    +5.59% (p=0.000 n=10)
FastRegexMatcher/.*foo.*|bar.*-10                         281.9n ±  0%    292.6n ±  3%    +3.81% (p=0.000 n=10)
FastRegexMatcher/foo.*|.*bar.*-10                         280.2n ±  0%    292.7n ±  1%    +4.46% (p=0.000 n=10)
FastRegexMatcher/.*foo.*|.*bar.*-10                       297.3n ±  0%    309.9n ±  1%    +4.24% (p=0.000 n=10)
FastRegexMatcher/.*foo.*bar.*|.*hello.*-10                13.77µ ±  0%    13.88µ ±  3%    +0.81% (p=0.001 n=10)
FastRegexMatcher/.*foo.*|.*bar.*|.*hello.*-10             486.6n ±  8%    477.0n ±  2%    -1.98% (p=0.005 n=10)
FastRegexMatcher/.+.*foo.*|.*bar.*-10                     16.06µ ±  1%    16.25µ ±  1%    +1.18% (p=0.001 n=10)
FastRegexMatcher/(?s:.*)-10                               53.60n ±  1%    54.04n ±  1%    +0.83% (p=0.020 n=10)
FastRegexMatcher/(?s:.+)-10                               56.15n ±  1%    56.41n ±  1%         ~ (p=0.225 n=10)
FastRegexMatcher/(?s:^.*foo$)-10                          113.5n ±  1%    110.7n ±  1%    -2.47% (p=0.000 n=10)
FastRegexMatcher/(?i:foo)-10                              81.41n ±  0%    83.53n ±  3%    +2.62% (p=0.019 n=10)
FastRegexMatcher/(?i:(foo|bar))-10                        169.6n ±  1%    171.6n ±  1%    +1.12% (p=0.008 n=10)
FastRegexMatcher/(?i:(foo1|foo2|bar))-10                  299.0n ±  1%    307.6n ±  2%    +2.86% (p=0.000 n=10)
FastRegexMatcher/^(?i:foo|oo)|(bar)$-10                   743.0n ± 14%    741.7n ±  2%         ~ (p=0.631 n=10)
FastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10      632.8n ±  4%    615.5n ±  2%    -2.72% (p=0.015 n=10)
FastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10           469.5n ±  9%    470.7n ±  2%         ~ (p=0.631 n=10)
FastRegexMatcher/^$-10                                    54.77n ±  2%    59.65n ±  7%    +8.91% (p=0.000 n=10)
FastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10       173.3n ±  0%    184.7n ±  9%    +6.58% (p=0.000 n=10)
FastRegexMatcher/10\.0\.(1|2)\.+-10                       87.20n ±  1%   453.45n ±  1%  +420.01% (p=0.000 n=10)
FastRegexMatcher/10\.0\.(1|2).+-10                        87.53n ±  3%   154.65n ±  1%   +76.67% (p=0.000 n=10)
FastRegexMatcher/((fo(bar))|.+foo)-10                     211.9n ±  0%    210.0n ±  1%    -0.87% (p=0.000 n=10)
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10      186.8n ± 15%    184.5n ± 15%         ~ (p=1.000 n=10)
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10      188.8n ±  9%    185.0n ±  5%         ~ (p=1.000 n=10)
FastRegexMatcher/.*zQPbMkNO.*|.*NNSPdvMi.*|.*iWuu-10      11.86µ ±  1%    12.08µ ±  2%    +1.91% (p=0.003 n=10)
FastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10      621.4n ±  4%    626.6n ±  3%         ~ (p=0.493 n=10)
FastRegexMatcher/(?i:(AAAAAAAAAAAAAAAAAAAAAAAA|BB-10      374.6n ±  0%    374.8n ±  1%         ~ (p=0.896 n=10)
FastRegexMatcher/(?i:(zQPbMkNO.*|NNSPdvMi.*|iWuuS-10      269.5n ±  0%    270.1n ±  1%         ~ (p=0.382 n=10)
FastRegexMatcher/(?i:(zQPbMkNO.*|NNSPdvMi.*|iWuuS#01-10   445.2n ±  1%    442.2n ±  1%         ~ (p=0.218 n=10)
FastRegexMatcher/(?i:(.*zQPbMkNO|.*NNSPdvMi|.*iWu-10      7.513µ ±  1%    7.502µ ±  1%         ~ (p=0.971 n=10)
FastRegexMatcher/fo.?-10                                  97.56n ±  0%    90.92n ±  4%    -6.81% (p=0.000 n=10)
FastRegexMatcher/foo.?-10                                 97.60n ±  0%    91.71n ±  1%    -6.03% (p=0.000 n=10)
FastRegexMatcher/f.?o-10                                  81.08n ±  1%   120.45n ±  1%   +48.57% (p=0.000 n=10)
FastRegexMatcher/.*foo.?-10                               202.5n ±  0%    194.2n ±  3%    -4.10% (p=0.001 n=10)
FastRegexMatcher/.?foo.+-10                               196.5n ±  0%    184.5n ±  3%    -6.11% (p=0.000 n=10)
FastRegexMatcher/foo.?|bar-10                             159.1n ±  4%    151.7n ±  0%    -4.65% (p=0.000 n=10)
FastRegexMatcher/ſſs-10                                   57.97n ±  0%    57.12n ±  2%    -1.46% (p=0.022 n=10)
FastRegexMatcher/.*-.*-.*-.*-.*-10                        200.3n ±  1%    180.6n ±  5%    -9.88% (p=0.000 n=10)
FastRegexMatcher/.+-.*-.*-.*-.+-10                        199.6n ±  1%    181.5n ±  2%    -9.07% (p=0.000 n=10)
FastRegexMatcher/-.*-.*-.*-.*-10                          98.13n ±  1%   182.10n ±  3%   +85.57% (p=0.000 n=10)
FastRegexMatcher/.*-.*-.*-.*--10                          115.1n ±  0%    108.5n ±  3%    -5.69% (p=0.000 n=10)
FastRegexMatcher/(.+)-(.+)-(.+)-(.+)-(.+)-10              199.5n ±  2%    181.5n ±  1%    -9.00% (p=0.000 n=10)
FastRegexMatcher/((.*))(?i:f)((.*))o((.*))o((.*))-10      4.335µ ±  0%    4.380µ ±  2%    +1.05% (p=0.004 n=10)
FastRegexMatcher/((.*))f((.*))(?i:o)((.*))o((.*))-10      3.548µ ±  0%    3.583µ ±  1%    +0.97% (p=0.012 n=10)
FastRegexMatcher/(.*0.*)-10                               131.0n ±  1%    115.7n ±  1%   -11.75% (p=0.000 n=10)
FastRegexMatcher/(?i).*foo.*-10                           7.654µ ±  0%    7.761µ ±  1%    +1.39% (p=0.000 n=10)
FastRegexMatcher/(?i)report.scheduled.job_runsche-10      168.9n ±  0%    167.4n ±  1%    -0.83% (p=0.001 n=10)
FastRegexMatcher/report.scheduled.job_runschedule-10      87.39n ±  0%    74.67n ±  2%   -14.54% (p=0.000 n=10)
FastRegexMatcher/(?i).*zQPbMkNO.*|.*NNSPdvMi.*|.*-10      1.154m ±  0%
FastRegexMatcher/(?i).*/label/.*|.*/labels.*|.*/s-10      19.23µ ±  1%
FastRegexMatcher/.*/label/.*|.*/labels.*|.*/serie-10      386.8n ±  5%
geomean                                                   273.9n          231.8n          +3.60%                ¹

@chencs chencs marked this pull request as ready for review May 13, 2026 17:34
@chencs chencs requested a review from a team as a code owner May 13, 2026 17:34
@chencs chencs requested a review from roidelapluie May 13, 2026 17:34

@bboreham bboreham left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

Comment thread model/labels/matcher.go Outdated
@chencs chencs force-pushed the case-insensitive-prefix-matching branch from 474fce7 to bf2244b Compare May 28, 2026 20:53
chencs added 2 commits May 28, 2026 13:56
Signed-off-by: Casie Chen <casie.chen@grafana.com>
Signed-off-by: Casie Chen <casie.chen@grafana.com>
@bboreham

bboreham commented Jun 2, 2026

Copy link
Copy Markdown
Member

OK, I filed this as an issue to come back to:

@bboreham bboreham merged commit 91fa0fd into prometheus:main Jun 2, 2026
35 checks passed
chencs added a commit to grafana/mimir that referenced this pull request Jun 30, 2026
prometheus/prometheus#18540 caused
`LabelValuesOffsets` to silently get case-insensitive prefixes but
execute them as case-sensitive prefixes. A fix has been merged upstream
and vendored in in #15902. This
introduces a test which would have caught that failure.
eleboucher pushed a commit to eleboucher/homelab that referenced this pull request Jul 1, 2026
…➔ v3.13.0) (#1360)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [quay.io/prometheus/prometheus](https://github.com/prometheus/prometheus) | minor | `v3.12.0` → `v3.13.0` |

---

### Release Notes

<details>
<summary>prometheus/prometheus (quay.io/prometheus/prometheus)</summary>

### [`v3.13.0`](https://github.com/prometheus/prometheus/releases/tag/v3.13.0): 3.13.0 / 2026-07-01

[Compare Source](prometheus/prometheus@v3.12.0...v3.13.0)

This is a Long Term Support [LTS](https://prometheus.io/docs/introduction/release-cycle/) release.

- \[SECURITY] UI: Bump `sanitize-html` to fix a cross-site scripting vulnerability (CVE-2026-44990). [#&#8203;18697](prometheus/prometheus#18697)
- \[CHANGE] UI: Third-party npm dependency licenses are now embedded in the Prometheus binary and served at `/assets/third-party-licenses.txt`, replacing the `npm_licenses.tar.bz2` archive previously shipped in release tarballs and container images. [#&#8203;18997](prometheus/prometheus#18997)
- \[CHANGE] API: Use SHA-256 instead of SHA-1 to generate rule group pagination tokens. [#&#8203;18927](prometheus/prometheus#18927)
- \[CHANGE] HTTP clients: Credentials (Authorization header, basic auth, bearer token, OAuth2, configured headers) are no longer forwarded when following a redirect to a different host; affects scraping, remote read/write, alerting, and service discovery. Via prometheus/common v0.69.0 (CVE-2025-4673 CVE-2023-45289). [#&#8203;18949](prometheus/prometheus#18949)
- \[CHANGE] promtool: Relative file paths in the file passed to `--http.config.file` are now resolved relative to that config file's directory instead of its parent directory. Via prometheus/common v0.69.0. [#&#8203;18949](prometheus/prometheus#18949)
- \[CHANGE] PromQL: Rename the `min()` and `max()` duration-expression functions (experimental feature flag `experimental-duration-expr`) to `min_of()` and `max_of()` to avoid confusion with the `min` and `max` aggregate operators. [#&#8203;18687](prometheus/prometheus#18687)
- \[FEATURE] API: Add experimental search endpoints to search metric names, label names, and label values. [#&#8203;18573](prometheus/prometheus#18573)
- \[FEATURE] Discovery/AWS: Add ability to filter RDS instances. [#&#8203;18859](prometheus/prometheus#18859)
- \[FEATURE] PromQL: Add `min_of(a, b)` and `max_of(a, b)` scalar experimental functions, returning the smaller or larger of two scalar values. [#&#8203;18687](prometheus/prometheus#18687)
- \[FEATURE] PromQL: Add support for smoothed/anchored rate with native histograms. [#&#8203;18564](prometheus/prometheus#18564)
- \[FEATURE] PromQL: Expose per-query `samplesRead` (and `samplesReadPerStep` with `stats=all` and the `promql-per-step-stats` feature flag) in the query stats response, and add the `prometheus_engine_query_samples_read_total` engine counter. `samplesRead` reflects storage I/O distinct from `totalQueryableSamples`, which counts samples loaded into the evaluator (and so over-counts when a sample is reused across multiple range-vector windows). [#&#8203;18081](prometheus/prometheus#18081)
- \[FEATURE] Scrape: Add `__convert_classic_histograms_to_nhcb__` internal label to allow per-target override of `convert_classic_histograms_to_nhcb` scrape configuration via relabeling. [#&#8203;18840](prometheus/prometheus#18840)
- \[FEATURE] TSDB: Add `storage.tsdb.chunk_encoding.floats` configuration field to select float chunk encoding (`xor` or `xor2`) at runtime, independently of the `--enable-feature=xor2-encoding` flag. [#&#8203;18769](prometheus/prometheus#18769)
- \[FEATURE] remote\_write: Add Certificate support for ingesting data into an Azure Monitor Workspace. [#&#8203;18217](prometheus/prometheus#18217)
- \[FEATURE] Scrape: Add `__always_scrape_classic_histograms__` and `__scrape_native_histograms__` internal labels to allow per-target override of the `always_scrape_classic_histograms` and `scrape_native_histograms` scrape configuration via relabeling. [#&#8203;18929](prometheus/prometheus#18929)
- \[ENHANCEMENT] Release: Container images are now also published to the GitHub Container Registry (ghcr.io). [#&#8203;18791](prometheus/prometheus#18791)
- \[ENHANCEMENT] PromQL: Prettify `fill_left(x) fill_right(x)` as `fill(x)` when both fill values are equal. [#&#8203;18851](prometheus/prometheus#18851)
- \[ENHANCEMENT] UI: Improve autocompletion after closing a function bracket. [#&#8203;18894](prometheus/prometheus#18894)
- \[PERF] Labels: Add case-insensitive prefix matching to speed up evaluation of long case-insensitive regular expressions (up to \~2x faster). [#&#8203;18540](prometheus/prometheus#18540)
- \[PERF] TSDB: Reduce per-sample overhead in chunk population, speeding up affected queries by \~12-15% in benchmarks. [#&#8203;18699](prometheus/prometheus#18699)
- \[PERF] TSDB: Eliminate unnecessary heap allocations in the V2 histogram WAL decoder, reducing allocations by up to 50% and memory by up to 10% for deployments using native histograms with created-timestamp storage enabled (`--enable-feature=created-timestamp-zero-ingestion`). [#&#8203;18813](prometheus/prometheus#18813)
- \[BUGFIX] Discovery/AWS: Fix failure when processing an AWS RDS cluster without instances. [#&#8203;18845](prometheus/prometheus#18845)
- \[BUGFIX] Fix race condition in initTime that could cause ErrOutOfBounds. [#&#8203;18629](prometheus/prometheus#18629)
- \[BUGFIX] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. [#&#8203;18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: A range query containing an at-modifier-unsafe function over a range-vector with an `@` modifier (e.g. `predict_linear(metric[60s] @&#8203; T, X)`) silently under-counted `totalQueryableSamples` for steps after step 0. [#&#8203;18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: Fix `fill_left`/`fill_right` producing missing samples in range queries when using `group_left`/`group_right`. [#&#8203;18850](prometheus/prometheus#18850)
- \[BUGFIX] PromQL: Fix for resets() and changes() in anchored range extenders with histograms. [#&#8203;18906](prometheus/prometheus#18906)
- \[BUGFIX] PromQL: Fix panic on `1[5m] smoothed` and similar expressions when extended range selectors are enabled. [#&#8203;18764](prometheus/prometheus#18764)
- \[BUGFIX] PromQL: Fix panic when a `smoothed` instant vector selector produces no samples for a series. [#&#8203;18943](prometheus/prometheus#18943)
- \[BUGFIX] PromQL: Fix panic when using a parenthesised plain number as an offset (e.g. `foo offset -(5)`). [#&#8203;18768](prometheus/prometheus#18768)
- \[BUGFIX] promtool: Fix panic when parsing exposition text containing empty braces `{}`. Via prometheus/common v0.69.0. [#&#8203;18949](prometheus/prometheus#18949)
- \[BUGFIX] Promtool: Fix `check healthy` and `check ready` when `--url` ends with a trailing slash. [#&#8203;18854](prometheus/prometheus#18854)
- \[BUGFIX] Rules: Close PromQL query after each rule evaluation to ensure resources are released. [#&#8203;18733](prometheus/prometheus#18733)
- \[BUGFIX] Scaleway SD: Resolve VPC/IPAM-only instances that have no legacy `private_ip` or `public_ip` field, but do have private NICs attached. [#&#8203;18772](prometheus/prometheus#18772)
- \[BUGFIX] TSDB: Do not leak head series when an integer histogram append is rejected (e.g. out-of-order). [#&#8203;18838](prometheus/prometheus#18838)
- \[BUGFIX] UI: Escape label values offered by PromQL autocomplete. [#&#8203;18658](prometheus/prometheus#18658)
- \[BUGFIX] TSDB: Fix chunk snapshot encoding for EncXOR2 chunks, preventing corruption on TSDB restart when EncXOR2-encoded series were present. [#&#8203;18739](prometheus/prometheus#18739)
- \[BUGFIX] TSDB: Store a millisecond timestamp (not a WAL segment number) in walExpiries when a series is evicted via CompactStaleHead/CompactSelectedSeries, so the series's label record is correctly retained in the next WAL checkpoint and replays cleanly. [#&#8203;18847](prometheus/prometheus#18847)
- \[BUGFIX] TSDB: Prevent loss of samples at the chunk-range boundary when CompactSelectedSeries (and CompactStaleHead) evict the series — the per-slice compaction loop now runs one more iteration so the boundary timestamp is captured in a block before the in-memory copy is removed. [#&#8203;18849](prometheus/prometheus#18849)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/1360
renovate Bot added a commit to sdwilsh/ansible-playbooks that referenced this pull request Jul 7, 2026
##### [\`v3.13.0\`](https://github.com/prometheus/prometheus/releases/tag/v3.13.0)

This is a Long Term Support [LTS](https://prometheus.io/docs/introduction/release-cycle/) release.

- \[SECURITY] UI: Bump `sanitize-html` to fix a cross-site scripting vulnerability (CVE-2026-44990). [#18697](prometheus/prometheus#18697)
- \[CHANGE] UI: Third-party npm dependency licenses are now embedded in the Prometheus binary and served at `/assets/third-party-licenses.txt`, replacing the `npm_licenses.tar.bz2` archive previously shipped in release tarballs and container images. [#18997](prometheus/prometheus#18997)
- \[CHANGE] API: Use SHA-256 instead of SHA-1 to generate rule group pagination tokens. [#18927](prometheus/prometheus#18927)
- \[CHANGE] HTTP clients: Credentials (Authorization header, basic auth, bearer token, OAuth2, configured headers) are no longer forwarded when following a redirect to a different host; affects scraping, remote read/write, alerting, and service discovery. Via prometheus/common v0.69.0 (CVE-2025-4673 CVE-2023-45289). [#18949](prometheus/prometheus#18949)
- \[CHANGE] promtool: Relative file paths in the file passed to `--http.config.file` are now resolved relative to that config file's directory instead of its parent directory. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[CHANGE] PromQL: Rename the `min()` and `max()` duration-expression functions (experimental feature flag `experimental-duration-expr`) to `min_of()` and `max_of()` to avoid confusion with the `min` and `max` aggregate operators. [#18687](prometheus/prometheus#18687)
- \[FEATURE] API: Add experimental search endpoints to search metric names, label names, and label values. [#18573](prometheus/prometheus#18573)
- \[FEATURE] Discovery/AWS: Add ability to filter RDS instances. [#18859](prometheus/prometheus#18859)
- \[FEATURE] PromQL: Add `min_of(a, b)` and `max_of(a, b)` scalar experimental functions, returning the smaller or larger of two scalar values. [#18687](prometheus/prometheus#18687)
- \[FEATURE] PromQL: Add support for smoothed/anchored rate with native histograms. [#18564](prometheus/prometheus#18564)
- \[FEATURE] PromQL: Expose per-query `samplesRead` (and `samplesReadPerStep` with `stats=all` and the `promql-per-step-stats` feature flag) in the query stats response, and add the `prometheus_engine_query_samples_read_total` engine counter. `samplesRead` reflects storage I/O distinct from `totalQueryableSamples`, which counts samples loaded into the evaluator (and so over-counts when a sample is reused across multiple range-vector windows). [#18081](prometheus/prometheus#18081)
- \[FEATURE] Scrape: Add `__convert_classic_histograms_to_nhcb__` internal label to allow per-target override of `convert_classic_histograms_to_nhcb` scrape configuration via relabeling. [#18840](prometheus/prometheus#18840)
- \[FEATURE] TSDB: Add `storage.tsdb.chunk_encoding.floats` configuration field to select float chunk encoding (`xor` or `xor2`) at runtime, independently of the `--enable-feature=xor2-encoding` flag. [#18769](prometheus/prometheus#18769)
- \[FEATURE] remote\_write: Add Certificate support for ingesting data into an Azure Monitor Workspace. [#18217](prometheus/prometheus#18217)
- \[FEATURE] Scrape: Add `__always_scrape_classic_histograms__` and `__scrape_native_histograms__` internal labels to allow per-target override of the `always_scrape_classic_histograms` and `scrape_native_histograms` scrape configuration via relabeling. [#18929](prometheus/prometheus#18929)
- \[ENHANCEMENT] Release: Container images are now also published to the GitHub Container Registry (ghcr.io). [#18791](prometheus/prometheus#18791)
- \[ENHANCEMENT] PromQL: Prettify `fill_left(x) fill_right(x)` as `fill(x)` when both fill values are equal. [#18851](prometheus/prometheus#18851)
- \[ENHANCEMENT] UI: Improve autocompletion after closing a function bracket. [#18894](prometheus/prometheus#18894)
- \[PERF] Labels: Add case-insensitive prefix matching to speed up evaluation of long case-insensitive regular expressions (up to \~2x faster). [#18540](prometheus/prometheus#18540)
- \[PERF] TSDB: Reduce per-sample overhead in chunk population, speeding up affected queries by \~12-15% in benchmarks. [#18699](prometheus/prometheus#18699)
- \[PERF] TSDB: Eliminate unnecessary heap allocations in the V2 histogram WAL decoder, reducing allocations by up to 50% and memory by up to 10% for deployments using native histograms with created-timestamp storage enabled (`--enable-feature=created-timestamp-zero-ingestion`). [#18813](prometheus/prometheus#18813)
- \[BUGFIX] Discovery/AWS: Fix failure when processing an AWS RDS cluster without instances. [#18845](prometheus/prometheus#18845)
- \[BUGFIX] Fix race condition in initTime that could cause ErrOutOfBounds. [#18629](prometheus/prometheus#18629)
- \[BUGFIX] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: A range query containing an at-modifier-unsafe function over a range-vector with an `@` modifier (e.g. `predict_linear(metric[60s] @ T, X)`) silently under-counted `totalQueryableSamples` for steps after step 0. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: Fix `fill_left`/`fill_right` producing missing samples in range queries when using `group_left`/`group_right`. [#18850](prometheus/prometheus#18850)
- \[BUGFIX] PromQL: Fix for resets() and changes() in anchored range extenders with histograms. [#18906](prometheus/prometheus#18906)
- \[BUGFIX] PromQL: Fix panic on `1[5m] smoothed` and similar expressions when extended range selectors are enabled. [#18764](prometheus/prometheus#18764)
- \[BUGFIX] PromQL: Fix panic when a `smoothed` instant vector selector produces no samples for a series. [#18943](prometheus/prometheus#18943)
- \[BUGFIX] PromQL: Fix panic when using a parenthesised plain number as an offset (e.g. `foo offset -(5)`). [#18768](prometheus/prometheus#18768)
- \[BUGFIX] promtool: Fix panic when parsing exposition text containing empty braces `{}`. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[BUGFIX] Promtool: Fix `check healthy` and `check ready` when `--url` ends with a trailing slash. [#18854](prometheus/prometheus#18854)
- \[BUGFIX] Rules: Close PromQL query after each rule evaluation to ensure resources are released. [#18733](prometheus/prometheus#18733)
- \[BUGFIX] Scaleway SD: Resolve VPC/IPAM-only instances that have no legacy `private_ip` or `public_ip` field, but do have private NICs attached. [#18772](prometheus/prometheus#18772)
- \[BUGFIX] TSDB: Do not leak head series when an integer histogram append is rejected (e.g. out-of-order). [#18838](prometheus/prometheus#18838)
- \[BUGFIX] UI: Escape label values offered by PromQL autocomplete. [#18658](prometheus/prometheus#18658)
- \[BUGFIX] TSDB: Fix chunk snapshot encoding for EncXOR2 chunks, preventing corruption on TSDB restart when EncXOR2-encoded series were present. [#18739](prometheus/prometheus#18739)
- \[BUGFIX] TSDB: Store a millisecond timestamp (not a WAL segment number) in walExpiries when a series is evicted via CompactStaleHead/CompactSelectedSeries, so the series's label record is correctly retained in the next WAL checkpoint and replays cleanly. [#18847](prometheus/prometheus#18847)
- \[BUGFIX] TSDB: Prevent loss of samples at the chunk-range boundary when CompactSelectedSeries (and CompactStaleHead) evict the series — the per-slice compaction loop now runs one more iteration so the boundary timestamp is captured in a block before the in-memory copy is removed. [#18849](prometheus/prometheus#18849)
renovate Bot added a commit to sdwilsh/ansible-playbooks that referenced this pull request Jul 7, 2026
##### [\`v3.13.0\`](https://github.com/prometheus/prometheus/releases/tag/v3.13.0)

This is a Long Term Support [LTS](https://prometheus.io/docs/introduction/release-cycle/) release.

- \[SECURITY] UI: Bump `sanitize-html` to fix a cross-site scripting vulnerability (CVE-2026-44990). [#18697](prometheus/prometheus#18697)
- \[CHANGE] UI: Third-party npm dependency licenses are now embedded in the Prometheus binary and served at `/assets/third-party-licenses.txt`, replacing the `npm_licenses.tar.bz2` archive previously shipped in release tarballs and container images. [#18997](prometheus/prometheus#18997)
- \[CHANGE] API: Use SHA-256 instead of SHA-1 to generate rule group pagination tokens. [#18927](prometheus/prometheus#18927)
- \[CHANGE] HTTP clients: Credentials (Authorization header, basic auth, bearer token, OAuth2, configured headers) are no longer forwarded when following a redirect to a different host; affects scraping, remote read/write, alerting, and service discovery. Via prometheus/common v0.69.0 (CVE-2025-4673 CVE-2023-45289). [#18949](prometheus/prometheus#18949)
- \[CHANGE] promtool: Relative file paths in the file passed to `--http.config.file` are now resolved relative to that config file's directory instead of its parent directory. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[CHANGE] PromQL: Rename the `min()` and `max()` duration-expression functions (experimental feature flag `experimental-duration-expr`) to `min_of()` and `max_of()` to avoid confusion with the `min` and `max` aggregate operators. [#18687](prometheus/prometheus#18687)
- \[FEATURE] API: Add experimental search endpoints to search metric names, label names, and label values. [#18573](prometheus/prometheus#18573)
- \[FEATURE] Discovery/AWS: Add ability to filter RDS instances. [#18859](prometheus/prometheus#18859)
- \[FEATURE] PromQL: Add `min_of(a, b)` and `max_of(a, b)` scalar experimental functions, returning the smaller or larger of two scalar values. [#18687](prometheus/prometheus#18687)
- \[FEATURE] PromQL: Add support for smoothed/anchored rate with native histograms. [#18564](prometheus/prometheus#18564)
- \[FEATURE] PromQL: Expose per-query `samplesRead` (and `samplesReadPerStep` with `stats=all` and the `promql-per-step-stats` feature flag) in the query stats response, and add the `prometheus_engine_query_samples_read_total` engine counter. `samplesRead` reflects storage I/O distinct from `totalQueryableSamples`, which counts samples loaded into the evaluator (and so over-counts when a sample is reused across multiple range-vector windows). [#18081](prometheus/prometheus#18081)
- \[FEATURE] Scrape: Add `__convert_classic_histograms_to_nhcb__` internal label to allow per-target override of `convert_classic_histograms_to_nhcb` scrape configuration via relabeling. [#18840](prometheus/prometheus#18840)
- \[FEATURE] TSDB: Add `storage.tsdb.chunk_encoding.floats` configuration field to select float chunk encoding (`xor` or `xor2`) at runtime, independently of the `--enable-feature=xor2-encoding` flag. [#18769](prometheus/prometheus#18769)
- \[FEATURE] remote\_write: Add Certificate support for ingesting data into an Azure Monitor Workspace. [#18217](prometheus/prometheus#18217)
- \[FEATURE] Scrape: Add `__always_scrape_classic_histograms__` and `__scrape_native_histograms__` internal labels to allow per-target override of the `always_scrape_classic_histograms` and `scrape_native_histograms` scrape configuration via relabeling. [#18929](prometheus/prometheus#18929)
- \[ENHANCEMENT] Release: Container images are now also published to the GitHub Container Registry (ghcr.io). [#18791](prometheus/prometheus#18791)
- \[ENHANCEMENT] PromQL: Prettify `fill_left(x) fill_right(x)` as `fill(x)` when both fill values are equal. [#18851](prometheus/prometheus#18851)
- \[ENHANCEMENT] UI: Improve autocompletion after closing a function bracket. [#18894](prometheus/prometheus#18894)
- \[PERF] Labels: Add case-insensitive prefix matching to speed up evaluation of long case-insensitive regular expressions (up to \~2x faster). [#18540](prometheus/prometheus#18540)
- \[PERF] TSDB: Reduce per-sample overhead in chunk population, speeding up affected queries by \~12-15% in benchmarks. [#18699](prometheus/prometheus#18699)
- \[PERF] TSDB: Eliminate unnecessary heap allocations in the V2 histogram WAL decoder, reducing allocations by up to 50% and memory by up to 10% for deployments using native histograms with created-timestamp storage enabled (`--enable-feature=created-timestamp-zero-ingestion`). [#18813](prometheus/prometheus#18813)
- \[BUGFIX] Discovery/AWS: Fix failure when processing an AWS RDS cluster without instances. [#18845](prometheus/prometheus#18845)
- \[BUGFIX] Fix race condition in initTime that could cause ErrOutOfBounds. [#18629](prometheus/prometheus#18629)
- \[BUGFIX] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: A range query containing an at-modifier-unsafe function over a range-vector with an `@` modifier (e.g. `predict_linear(metric[60s] @ T, X)`) silently under-counted `totalQueryableSamples` for steps after step 0. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: Fix `fill_left`/`fill_right` producing missing samples in range queries when using `group_left`/`group_right`. [#18850](prometheus/prometheus#18850)
- \[BUGFIX] PromQL: Fix for resets() and changes() in anchored range extenders with histograms. [#18906](prometheus/prometheus#18906)
- \[BUGFIX] PromQL: Fix panic on `1[5m] smoothed` and similar expressions when extended range selectors are enabled. [#18764](prometheus/prometheus#18764)
- \[BUGFIX] PromQL: Fix panic when a `smoothed` instant vector selector produces no samples for a series. [#18943](prometheus/prometheus#18943)
- \[BUGFIX] PromQL: Fix panic when using a parenthesised plain number as an offset (e.g. `foo offset -(5)`). [#18768](prometheus/prometheus#18768)
- \[BUGFIX] promtool: Fix panic when parsing exposition text containing empty braces `{}`. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[BUGFIX] Promtool: Fix `check healthy` and `check ready` when `--url` ends with a trailing slash. [#18854](prometheus/prometheus#18854)
- \[BUGFIX] Rules: Close PromQL query after each rule evaluation to ensure resources are released. [#18733](prometheus/prometheus#18733)
- \[BUGFIX] Scaleway SD: Resolve VPC/IPAM-only instances that have no legacy `private_ip` or `public_ip` field, but do have private NICs attached. [#18772](prometheus/prometheus#18772)
- \[BUGFIX] TSDB: Do not leak head series when an integer histogram append is rejected (e.g. out-of-order). [#18838](prometheus/prometheus#18838)
- \[BUGFIX] UI: Escape label values offered by PromQL autocomplete. [#18658](prometheus/prometheus#18658)
- \[BUGFIX] TSDB: Fix chunk snapshot encoding for EncXOR2 chunks, preventing corruption on TSDB restart when EncXOR2-encoded series were present. [#18739](prometheus/prometheus#18739)
- \[BUGFIX] TSDB: Store a millisecond timestamp (not a WAL segment number) in walExpiries when a series is evicted via CompactStaleHead/CompactSelectedSeries, so the series's label record is correctly retained in the next WAL checkpoint and replays cleanly. [#18847](prometheus/prometheus#18847)
- \[BUGFIX] TSDB: Prevent loss of samples at the chunk-range boundary when CompactSelectedSeries (and CompactStaleHead) evict the series — the per-slice compaction loop now runs one more iteration so the boundary timestamp is captured in a block before the in-memory copy is removed. [#18849](prometheus/prometheus#18849)
renovate Bot added a commit to sdwilsh/ansible-playbooks that referenced this pull request Jul 7, 2026
##### [\`v3.13.0\`](https://github.com/prometheus/prometheus/releases/tag/v3.13.0)

This is a Long Term Support [LTS](https://prometheus.io/docs/introduction/release-cycle/) release.

- \[SECURITY] UI: Bump `sanitize-html` to fix a cross-site scripting vulnerability (CVE-2026-44990). [#18697](prometheus/prometheus#18697)
- \[CHANGE] UI: Third-party npm dependency licenses are now embedded in the Prometheus binary and served at `/assets/third-party-licenses.txt`, replacing the `npm_licenses.tar.bz2` archive previously shipped in release tarballs and container images. [#18997](prometheus/prometheus#18997)
- \[CHANGE] API: Use SHA-256 instead of SHA-1 to generate rule group pagination tokens. [#18927](prometheus/prometheus#18927)
- \[CHANGE] HTTP clients: Credentials (Authorization header, basic auth, bearer token, OAuth2, configured headers) are no longer forwarded when following a redirect to a different host; affects scraping, remote read/write, alerting, and service discovery. Via prometheus/common v0.69.0 (CVE-2025-4673 CVE-2023-45289). [#18949](prometheus/prometheus#18949)
- \[CHANGE] promtool: Relative file paths in the file passed to `--http.config.file` are now resolved relative to that config file's directory instead of its parent directory. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[CHANGE] PromQL: Rename the `min()` and `max()` duration-expression functions (experimental feature flag `experimental-duration-expr`) to `min_of()` and `max_of()` to avoid confusion with the `min` and `max` aggregate operators. [#18687](prometheus/prometheus#18687)
- \[FEATURE] API: Add experimental search endpoints to search metric names, label names, and label values. [#18573](prometheus/prometheus#18573)
- \[FEATURE] Discovery/AWS: Add ability to filter RDS instances. [#18859](prometheus/prometheus#18859)
- \[FEATURE] PromQL: Add `min_of(a, b)` and `max_of(a, b)` scalar experimental functions, returning the smaller or larger of two scalar values. [#18687](prometheus/prometheus#18687)
- \[FEATURE] PromQL: Add support for smoothed/anchored rate with native histograms. [#18564](prometheus/prometheus#18564)
- \[FEATURE] PromQL: Expose per-query `samplesRead` (and `samplesReadPerStep` with `stats=all` and the `promql-per-step-stats` feature flag) in the query stats response, and add the `prometheus_engine_query_samples_read_total` engine counter. `samplesRead` reflects storage I/O distinct from `totalQueryableSamples`, which counts samples loaded into the evaluator (and so over-counts when a sample is reused across multiple range-vector windows). [#18081](prometheus/prometheus#18081)
- \[FEATURE] Scrape: Add `__convert_classic_histograms_to_nhcb__` internal label to allow per-target override of `convert_classic_histograms_to_nhcb` scrape configuration via relabeling. [#18840](prometheus/prometheus#18840)
- \[FEATURE] TSDB: Add `storage.tsdb.chunk_encoding.floats` configuration field to select float chunk encoding (`xor` or `xor2`) at runtime, independently of the `--enable-feature=xor2-encoding` flag. [#18769](prometheus/prometheus#18769)
- \[FEATURE] remote\_write: Add Certificate support for ingesting data into an Azure Monitor Workspace. [#18217](prometheus/prometheus#18217)
- \[FEATURE] Scrape: Add `__always_scrape_classic_histograms__` and `__scrape_native_histograms__` internal labels to allow per-target override of the `always_scrape_classic_histograms` and `scrape_native_histograms` scrape configuration via relabeling. [#18929](prometheus/prometheus#18929)
- \[ENHANCEMENT] Release: Container images are now also published to the GitHub Container Registry (ghcr.io). [#18791](prometheus/prometheus#18791)
- \[ENHANCEMENT] PromQL: Prettify `fill_left(x) fill_right(x)` as `fill(x)` when both fill values are equal. [#18851](prometheus/prometheus#18851)
- \[ENHANCEMENT] UI: Improve autocompletion after closing a function bracket. [#18894](prometheus/prometheus#18894)
- \[PERF] Labels: Add case-insensitive prefix matching to speed up evaluation of long case-insensitive regular expressions (up to \~2x faster). [#18540](prometheus/prometheus#18540)
- \[PERF] TSDB: Reduce per-sample overhead in chunk population, speeding up affected queries by \~12-15% in benchmarks. [#18699](prometheus/prometheus#18699)
- \[PERF] TSDB: Eliminate unnecessary heap allocations in the V2 histogram WAL decoder, reducing allocations by up to 50% and memory by up to 10% for deployments using native histograms with created-timestamp storage enabled (`--enable-feature=created-timestamp-zero-ingestion`). [#18813](prometheus/prometheus#18813)
- \[BUGFIX] Discovery/AWS: Fix failure when processing an AWS RDS cluster without instances. [#18845](prometheus/prometheus#18845)
- \[BUGFIX] Fix race condition in initTime that could cause ErrOutOfBounds. [#18629](prometheus/prometheus#18629)
- \[BUGFIX] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: A range query containing an at-modifier-unsafe function over a range-vector with an `@` modifier (e.g. `predict_linear(metric[60s] @ T, X)`) silently under-counted `totalQueryableSamples` for steps after step 0. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: Fix `fill_left`/`fill_right` producing missing samples in range queries when using `group_left`/`group_right`. [#18850](prometheus/prometheus#18850)
- \[BUGFIX] PromQL: Fix for resets() and changes() in anchored range extenders with histograms. [#18906](prometheus/prometheus#18906)
- \[BUGFIX] PromQL: Fix panic on `1[5m] smoothed` and similar expressions when extended range selectors are enabled. [#18764](prometheus/prometheus#18764)
- \[BUGFIX] PromQL: Fix panic when a `smoothed` instant vector selector produces no samples for a series. [#18943](prometheus/prometheus#18943)
- \[BUGFIX] PromQL: Fix panic when using a parenthesised plain number as an offset (e.g. `foo offset -(5)`). [#18768](prometheus/prometheus#18768)
- \[BUGFIX] promtool: Fix panic when parsing exposition text containing empty braces `{}`. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[BUGFIX] Promtool: Fix `check healthy` and `check ready` when `--url` ends with a trailing slash. [#18854](prometheus/prometheus#18854)
- \[BUGFIX] Rules: Close PromQL query after each rule evaluation to ensure resources are released. [#18733](prometheus/prometheus#18733)
- \[BUGFIX] Scaleway SD: Resolve VPC/IPAM-only instances that have no legacy `private_ip` or `public_ip` field, but do have private NICs attached. [#18772](prometheus/prometheus#18772)
- \[BUGFIX] TSDB: Do not leak head series when an integer histogram append is rejected (e.g. out-of-order). [#18838](prometheus/prometheus#18838)
- \[BUGFIX] UI: Escape label values offered by PromQL autocomplete. [#18658](prometheus/prometheus#18658)
- \[BUGFIX] TSDB: Fix chunk snapshot encoding for EncXOR2 chunks, preventing corruption on TSDB restart when EncXOR2-encoded series were present. [#18739](prometheus/prometheus#18739)
- \[BUGFIX] TSDB: Store a millisecond timestamp (not a WAL segment number) in walExpiries when a series is evicted via CompactStaleHead/CompactSelectedSeries, so the series's label record is correctly retained in the next WAL checkpoint and replays cleanly. [#18847](prometheus/prometheus#18847)
- \[BUGFIX] TSDB: Prevent loss of samples at the chunk-range boundary when CompactSelectedSeries (and CompactStaleHead) evict the series — the per-slice compaction loop now runs one more iteration so the boundary timestamp is captured in a block before the in-memory copy is removed. [#18849](prometheus/prometheus#18849)
renovate Bot added a commit to sdwilsh/ansible-playbooks that referenced this pull request Jul 7, 2026
##### [\`v3.13.0\`](https://github.com/prometheus/prometheus/releases/tag/v3.13.0)

This is a Long Term Support [LTS](https://prometheus.io/docs/introduction/release-cycle/) release.

- \[SECURITY] UI: Bump `sanitize-html` to fix a cross-site scripting vulnerability (CVE-2026-44990). [#18697](prometheus/prometheus#18697)
- \[CHANGE] UI: Third-party npm dependency licenses are now embedded in the Prometheus binary and served at `/assets/third-party-licenses.txt`, replacing the `npm_licenses.tar.bz2` archive previously shipped in release tarballs and container images. [#18997](prometheus/prometheus#18997)
- \[CHANGE] API: Use SHA-256 instead of SHA-1 to generate rule group pagination tokens. [#18927](prometheus/prometheus#18927)
- \[CHANGE] HTTP clients: Credentials (Authorization header, basic auth, bearer token, OAuth2, configured headers) are no longer forwarded when following a redirect to a different host; affects scraping, remote read/write, alerting, and service discovery. Via prometheus/common v0.69.0 (CVE-2025-4673 CVE-2023-45289). [#18949](prometheus/prometheus#18949)
- \[CHANGE] promtool: Relative file paths in the file passed to `--http.config.file` are now resolved relative to that config file's directory instead of its parent directory. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[CHANGE] PromQL: Rename the `min()` and `max()` duration-expression functions (experimental feature flag `experimental-duration-expr`) to `min_of()` and `max_of()` to avoid confusion with the `min` and `max` aggregate operators. [#18687](prometheus/prometheus#18687)
- \[FEATURE] API: Add experimental search endpoints to search metric names, label names, and label values. [#18573](prometheus/prometheus#18573)
- \[FEATURE] Discovery/AWS: Add ability to filter RDS instances. [#18859](prometheus/prometheus#18859)
- \[FEATURE] PromQL: Add `min_of(a, b)` and `max_of(a, b)` scalar experimental functions, returning the smaller or larger of two scalar values. [#18687](prometheus/prometheus#18687)
- \[FEATURE] PromQL: Add support for smoothed/anchored rate with native histograms. [#18564](prometheus/prometheus#18564)
- \[FEATURE] PromQL: Expose per-query `samplesRead` (and `samplesReadPerStep` with `stats=all` and the `promql-per-step-stats` feature flag) in the query stats response, and add the `prometheus_engine_query_samples_read_total` engine counter. `samplesRead` reflects storage I/O distinct from `totalQueryableSamples`, which counts samples loaded into the evaluator (and so over-counts when a sample is reused across multiple range-vector windows). [#18081](prometheus/prometheus#18081)
- \[FEATURE] Scrape: Add `__convert_classic_histograms_to_nhcb__` internal label to allow per-target override of `convert_classic_histograms_to_nhcb` scrape configuration via relabeling. [#18840](prometheus/prometheus#18840)
- \[FEATURE] TSDB: Add `storage.tsdb.chunk_encoding.floats` configuration field to select float chunk encoding (`xor` or `xor2`) at runtime, independently of the `--enable-feature=xor2-encoding` flag. [#18769](prometheus/prometheus#18769)
- \[FEATURE] remote\_write: Add Certificate support for ingesting data into an Azure Monitor Workspace. [#18217](prometheus/prometheus#18217)
- \[FEATURE] Scrape: Add `__always_scrape_classic_histograms__` and `__scrape_native_histograms__` internal labels to allow per-target override of the `always_scrape_classic_histograms` and `scrape_native_histograms` scrape configuration via relabeling. [#18929](prometheus/prometheus#18929)
- \[ENHANCEMENT] Release: Container images are now also published to the GitHub Container Registry (ghcr.io). [#18791](prometheus/prometheus#18791)
- \[ENHANCEMENT] PromQL: Prettify `fill_left(x) fill_right(x)` as `fill(x)` when both fill values are equal. [#18851](prometheus/prometheus#18851)
- \[ENHANCEMENT] UI: Improve autocompletion after closing a function bracket. [#18894](prometheus/prometheus#18894)
- \[PERF] Labels: Add case-insensitive prefix matching to speed up evaluation of long case-insensitive regular expressions (up to \~2x faster). [#18540](prometheus/prometheus#18540)
- \[PERF] TSDB: Reduce per-sample overhead in chunk population, speeding up affected queries by \~12-15% in benchmarks. [#18699](prometheus/prometheus#18699)
- \[PERF] TSDB: Eliminate unnecessary heap allocations in the V2 histogram WAL decoder, reducing allocations by up to 50% and memory by up to 10% for deployments using native histograms with created-timestamp storage enabled (`--enable-feature=created-timestamp-zero-ingestion`). [#18813](prometheus/prometheus#18813)
- \[BUGFIX] Discovery/AWS: Fix failure when processing an AWS RDS cluster without instances. [#18845](prometheus/prometheus#18845)
- \[BUGFIX] Fix race condition in initTime that could cause ErrOutOfBounds. [#18629](prometheus/prometheus#18629)
- \[BUGFIX] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: A range query containing an at-modifier-unsafe function over a range-vector with an `@` modifier (e.g. `predict_linear(metric[60s] @ T, X)`) silently under-counted `totalQueryableSamples` for steps after step 0. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: Fix `fill_left`/`fill_right` producing missing samples in range queries when using `group_left`/`group_right`. [#18850](prometheus/prometheus#18850)
- \[BUGFIX] PromQL: Fix for resets() and changes() in anchored range extenders with histograms. [#18906](prometheus/prometheus#18906)
- \[BUGFIX] PromQL: Fix panic on `1[5m] smoothed` and similar expressions when extended range selectors are enabled. [#18764](prometheus/prometheus#18764)
- \[BUGFIX] PromQL: Fix panic when a `smoothed` instant vector selector produces no samples for a series. [#18943](prometheus/prometheus#18943)
- \[BUGFIX] PromQL: Fix panic when using a parenthesised plain number as an offset (e.g. `foo offset -(5)`). [#18768](prometheus/prometheus#18768)
- \[BUGFIX] promtool: Fix panic when parsing exposition text containing empty braces `{}`. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[BUGFIX] Promtool: Fix `check healthy` and `check ready` when `--url` ends with a trailing slash. [#18854](prometheus/prometheus#18854)
- \[BUGFIX] Rules: Close PromQL query after each rule evaluation to ensure resources are released. [#18733](prometheus/prometheus#18733)
- \[BUGFIX] Scaleway SD: Resolve VPC/IPAM-only instances that have no legacy `private_ip` or `public_ip` field, but do have private NICs attached. [#18772](prometheus/prometheus#18772)
- \[BUGFIX] TSDB: Do not leak head series when an integer histogram append is rejected (e.g. out-of-order). [#18838](prometheus/prometheus#18838)
- \[BUGFIX] UI: Escape label values offered by PromQL autocomplete. [#18658](prometheus/prometheus#18658)
- \[BUGFIX] TSDB: Fix chunk snapshot encoding for EncXOR2 chunks, preventing corruption on TSDB restart when EncXOR2-encoded series were present. [#18739](prometheus/prometheus#18739)
- \[BUGFIX] TSDB: Store a millisecond timestamp (not a WAL segment number) in walExpiries when a series is evicted via CompactStaleHead/CompactSelectedSeries, so the series's label record is correctly retained in the next WAL checkpoint and replays cleanly. [#18847](prometheus/prometheus#18847)
- \[BUGFIX] TSDB: Prevent loss of samples at the chunk-range boundary when CompactSelectedSeries (and CompactStaleHead) evict the series — the per-slice compaction loop now runs one more iteration so the boundary timestamp is captured in a block before the in-memory copy is removed. [#18849](prometheus/prometheus#18849)
renovate Bot added a commit to sdwilsh/ansible-playbooks that referenced this pull request Jul 7, 2026
##### [\`v3.13.0\`](https://github.com/prometheus/prometheus/releases/tag/v3.13.0)

This is a Long Term Support [LTS](https://prometheus.io/docs/introduction/release-cycle/) release.

- \[SECURITY] UI: Bump `sanitize-html` to fix a cross-site scripting vulnerability (CVE-2026-44990). [#18697](prometheus/prometheus#18697)
- \[CHANGE] UI: Third-party npm dependency licenses are now embedded in the Prometheus binary and served at `/assets/third-party-licenses.txt`, replacing the `npm_licenses.tar.bz2` archive previously shipped in release tarballs and container images. [#18997](prometheus/prometheus#18997)
- \[CHANGE] API: Use SHA-256 instead of SHA-1 to generate rule group pagination tokens. [#18927](prometheus/prometheus#18927)
- \[CHANGE] HTTP clients: Credentials (Authorization header, basic auth, bearer token, OAuth2, configured headers) are no longer forwarded when following a redirect to a different host; affects scraping, remote read/write, alerting, and service discovery. Via prometheus/common v0.69.0 (CVE-2025-4673 CVE-2023-45289). [#18949](prometheus/prometheus#18949)
- \[CHANGE] promtool: Relative file paths in the file passed to `--http.config.file` are now resolved relative to that config file's directory instead of its parent directory. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[CHANGE] PromQL: Rename the `min()` and `max()` duration-expression functions (experimental feature flag `experimental-duration-expr`) to `min_of()` and `max_of()` to avoid confusion with the `min` and `max` aggregate operators. [#18687](prometheus/prometheus#18687)
- \[FEATURE] API: Add experimental search endpoints to search metric names, label names, and label values. [#18573](prometheus/prometheus#18573)
- \[FEATURE] Discovery/AWS: Add ability to filter RDS instances. [#18859](prometheus/prometheus#18859)
- \[FEATURE] PromQL: Add `min_of(a, b)` and `max_of(a, b)` scalar experimental functions, returning the smaller or larger of two scalar values. [#18687](prometheus/prometheus#18687)
- \[FEATURE] PromQL: Add support for smoothed/anchored rate with native histograms. [#18564](prometheus/prometheus#18564)
- \[FEATURE] PromQL: Expose per-query `samplesRead` (and `samplesReadPerStep` with `stats=all` and the `promql-per-step-stats` feature flag) in the query stats response, and add the `prometheus_engine_query_samples_read_total` engine counter. `samplesRead` reflects storage I/O distinct from `totalQueryableSamples`, which counts samples loaded into the evaluator (and so over-counts when a sample is reused across multiple range-vector windows). [#18081](prometheus/prometheus#18081)
- \[FEATURE] Scrape: Add `__convert_classic_histograms_to_nhcb__` internal label to allow per-target override of `convert_classic_histograms_to_nhcb` scrape configuration via relabeling. [#18840](prometheus/prometheus#18840)
- \[FEATURE] TSDB: Add `storage.tsdb.chunk_encoding.floats` configuration field to select float chunk encoding (`xor` or `xor2`) at runtime, independently of the `--enable-feature=xor2-encoding` flag. [#18769](prometheus/prometheus#18769)
- \[FEATURE] remote\_write: Add Certificate support for ingesting data into an Azure Monitor Workspace. [#18217](prometheus/prometheus#18217)
- \[FEATURE] Scrape: Add `__always_scrape_classic_histograms__` and `__scrape_native_histograms__` internal labels to allow per-target override of the `always_scrape_classic_histograms` and `scrape_native_histograms` scrape configuration via relabeling. [#18929](prometheus/prometheus#18929)
- \[ENHANCEMENT] Release: Container images are now also published to the GitHub Container Registry (ghcr.io). [#18791](prometheus/prometheus#18791)
- \[ENHANCEMENT] PromQL: Prettify `fill_left(x) fill_right(x)` as `fill(x)` when both fill values are equal. [#18851](prometheus/prometheus#18851)
- \[ENHANCEMENT] UI: Improve autocompletion after closing a function bracket. [#18894](prometheus/prometheus#18894)
- \[PERF] Labels: Add case-insensitive prefix matching to speed up evaluation of long case-insensitive regular expressions (up to \~2x faster). [#18540](prometheus/prometheus#18540)
- \[PERF] TSDB: Reduce per-sample overhead in chunk population, speeding up affected queries by \~12-15% in benchmarks. [#18699](prometheus/prometheus#18699)
- \[PERF] TSDB: Eliminate unnecessary heap allocations in the V2 histogram WAL decoder, reducing allocations by up to 50% and memory by up to 10% for deployments using native histograms with created-timestamp storage enabled (`--enable-feature=created-timestamp-zero-ingestion`). [#18813](prometheus/prometheus#18813)
- \[BUGFIX] Discovery/AWS: Fix failure when processing an AWS RDS cluster without instances. [#18845](prometheus/prometheus#18845)
- \[BUGFIX] Fix race condition in initTime that could cause ErrOutOfBounds. [#18629](prometheus/prometheus#18629)
- \[BUGFIX] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: A range query containing an at-modifier-unsafe function over a range-vector with an `@` modifier (e.g. `predict_linear(metric[60s] @ T, X)`) silently under-counted `totalQueryableSamples` for steps after step 0. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: Fix `fill_left`/`fill_right` producing missing samples in range queries when using `group_left`/`group_right`. [#18850](prometheus/prometheus#18850)
- \[BUGFIX] PromQL: Fix for resets() and changes() in anchored range extenders with histograms. [#18906](prometheus/prometheus#18906)
- \[BUGFIX] PromQL: Fix panic on `1[5m] smoothed` and similar expressions when extended range selectors are enabled. [#18764](prometheus/prometheus#18764)
- \[BUGFIX] PromQL: Fix panic when a `smoothed` instant vector selector produces no samples for a series. [#18943](prometheus/prometheus#18943)
- \[BUGFIX] PromQL: Fix panic when using a parenthesised plain number as an offset (e.g. `foo offset -(5)`). [#18768](prometheus/prometheus#18768)
- \[BUGFIX] promtool: Fix panic when parsing exposition text containing empty braces `{}`. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[BUGFIX] Promtool: Fix `check healthy` and `check ready` when `--url` ends with a trailing slash. [#18854](prometheus/prometheus#18854)
- \[BUGFIX] Rules: Close PromQL query after each rule evaluation to ensure resources are released. [#18733](prometheus/prometheus#18733)
- \[BUGFIX] Scaleway SD: Resolve VPC/IPAM-only instances that have no legacy `private_ip` or `public_ip` field, but do have private NICs attached. [#18772](prometheus/prometheus#18772)
- \[BUGFIX] TSDB: Do not leak head series when an integer histogram append is rejected (e.g. out-of-order). [#18838](prometheus/prometheus#18838)
- \[BUGFIX] UI: Escape label values offered by PromQL autocomplete. [#18658](prometheus/prometheus#18658)
- \[BUGFIX] TSDB: Fix chunk snapshot encoding for EncXOR2 chunks, preventing corruption on TSDB restart when EncXOR2-encoded series were present. [#18739](prometheus/prometheus#18739)
- \[BUGFIX] TSDB: Store a millisecond timestamp (not a WAL segment number) in walExpiries when a series is evicted via CompactStaleHead/CompactSelectedSeries, so the series's label record is correctly retained in the next WAL checkpoint and replays cleanly. [#18847](prometheus/prometheus#18847)
- \[BUGFIX] TSDB: Prevent loss of samples at the chunk-range boundary when CompactSelectedSeries (and CompactStaleHead) evict the series — the per-slice compaction loop now runs one more iteration so the boundary timestamp is captured in a block before the in-memory copy is removed. [#18849](prometheus/prometheus#18849)
renovate Bot added a commit to sdwilsh/ansible-playbooks that referenced this pull request Jul 7, 2026
##### [\`v3.13.0\`](https://github.com/prometheus/prometheus/releases/tag/v3.13.0)

This is a Long Term Support [LTS](https://prometheus.io/docs/introduction/release-cycle/) release.

- \[SECURITY] UI: Bump `sanitize-html` to fix a cross-site scripting vulnerability (CVE-2026-44990). [#18697](prometheus/prometheus#18697)
- \[CHANGE] UI: Third-party npm dependency licenses are now embedded in the Prometheus binary and served at `/assets/third-party-licenses.txt`, replacing the `npm_licenses.tar.bz2` archive previously shipped in release tarballs and container images. [#18997](prometheus/prometheus#18997)
- \[CHANGE] API: Use SHA-256 instead of SHA-1 to generate rule group pagination tokens. [#18927](prometheus/prometheus#18927)
- \[CHANGE] HTTP clients: Credentials (Authorization header, basic auth, bearer token, OAuth2, configured headers) are no longer forwarded when following a redirect to a different host; affects scraping, remote read/write, alerting, and service discovery. Via prometheus/common v0.69.0 (CVE-2025-4673 CVE-2023-45289). [#18949](prometheus/prometheus#18949)
- \[CHANGE] promtool: Relative file paths in the file passed to `--http.config.file` are now resolved relative to that config file's directory instead of its parent directory. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[CHANGE] PromQL: Rename the `min()` and `max()` duration-expression functions (experimental feature flag `experimental-duration-expr`) to `min_of()` and `max_of()` to avoid confusion with the `min` and `max` aggregate operators. [#18687](prometheus/prometheus#18687)
- \[FEATURE] API: Add experimental search endpoints to search metric names, label names, and label values. [#18573](prometheus/prometheus#18573)
- \[FEATURE] Discovery/AWS: Add ability to filter RDS instances. [#18859](prometheus/prometheus#18859)
- \[FEATURE] PromQL: Add `min_of(a, b)` and `max_of(a, b)` scalar experimental functions, returning the smaller or larger of two scalar values. [#18687](prometheus/prometheus#18687)
- \[FEATURE] PromQL: Add support for smoothed/anchored rate with native histograms. [#18564](prometheus/prometheus#18564)
- \[FEATURE] PromQL: Expose per-query `samplesRead` (and `samplesReadPerStep` with `stats=all` and the `promql-per-step-stats` feature flag) in the query stats response, and add the `prometheus_engine_query_samples_read_total` engine counter. `samplesRead` reflects storage I/O distinct from `totalQueryableSamples`, which counts samples loaded into the evaluator (and so over-counts when a sample is reused across multiple range-vector windows). [#18081](prometheus/prometheus#18081)
- \[FEATURE] Scrape: Add `__convert_classic_histograms_to_nhcb__` internal label to allow per-target override of `convert_classic_histograms_to_nhcb` scrape configuration via relabeling. [#18840](prometheus/prometheus#18840)
- \[FEATURE] TSDB: Add `storage.tsdb.chunk_encoding.floats` configuration field to select float chunk encoding (`xor` or `xor2`) at runtime, independently of the `--enable-feature=xor2-encoding` flag. [#18769](prometheus/prometheus#18769)
- \[FEATURE] remote\_write: Add Certificate support for ingesting data into an Azure Monitor Workspace. [#18217](prometheus/prometheus#18217)
- \[FEATURE] Scrape: Add `__always_scrape_classic_histograms__` and `__scrape_native_histograms__` internal labels to allow per-target override of the `always_scrape_classic_histograms` and `scrape_native_histograms` scrape configuration via relabeling. [#18929](prometheus/prometheus#18929)
- \[ENHANCEMENT] Release: Container images are now also published to the GitHub Container Registry (ghcr.io). [#18791](prometheus/prometheus#18791)
- \[ENHANCEMENT] PromQL: Prettify `fill_left(x) fill_right(x)` as `fill(x)` when both fill values are equal. [#18851](prometheus/prometheus#18851)
- \[ENHANCEMENT] UI: Improve autocompletion after closing a function bracket. [#18894](prometheus/prometheus#18894)
- \[PERF] Labels: Add case-insensitive prefix matching to speed up evaluation of long case-insensitive regular expressions (up to \~2x faster). [#18540](prometheus/prometheus#18540)
- \[PERF] TSDB: Reduce per-sample overhead in chunk population, speeding up affected queries by \~12-15% in benchmarks. [#18699](prometheus/prometheus#18699)
- \[PERF] TSDB: Eliminate unnecessary heap allocations in the V2 histogram WAL decoder, reducing allocations by up to 50% and memory by up to 10% for deployments using native histograms with created-timestamp storage enabled (`--enable-feature=created-timestamp-zero-ingestion`). [#18813](prometheus/prometheus#18813)
- \[BUGFIX] Discovery/AWS: Fix failure when processing an AWS RDS cluster without instances. [#18845](prometheus/prometheus#18845)
- \[BUGFIX] Fix race condition in initTime that could cause ErrOutOfBounds. [#18629](prometheus/prometheus#18629)
- \[BUGFIX] PromQL: A range query whose `end` was not aligned to `step` caused subqueries inside it to evaluate past the parent's last actual step, inflating `peakSamples` in the query stats and against the `query.max-samples` limit, and wasting storage I/O reading samples that were never used in the result. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: A range query containing an at-modifier-unsafe function over a range-vector with an `@` modifier (e.g. `predict_linear(metric[60s] @ T, X)`) silently under-counted `totalQueryableSamples` for steps after step 0. [#18081](prometheus/prometheus#18081)
- \[BUGFIX] PromQL: Fix `fill_left`/`fill_right` producing missing samples in range queries when using `group_left`/`group_right`. [#18850](prometheus/prometheus#18850)
- \[BUGFIX] PromQL: Fix for resets() and changes() in anchored range extenders with histograms. [#18906](prometheus/prometheus#18906)
- \[BUGFIX] PromQL: Fix panic on `1[5m] smoothed` and similar expressions when extended range selectors are enabled. [#18764](prometheus/prometheus#18764)
- \[BUGFIX] PromQL: Fix panic when a `smoothed` instant vector selector produces no samples for a series. [#18943](prometheus/prometheus#18943)
- \[BUGFIX] PromQL: Fix panic when using a parenthesised plain number as an offset (e.g. `foo offset -(5)`). [#18768](prometheus/prometheus#18768)
- \[BUGFIX] promtool: Fix panic when parsing exposition text containing empty braces `{}`. Via prometheus/common v0.69.0. [#18949](prometheus/prometheus#18949)
- \[BUGFIX] Promtool: Fix `check healthy` and `check ready` when `--url` ends with a trailing slash. [#18854](prometheus/prometheus#18854)
- \[BUGFIX] Rules: Close PromQL query after each rule evaluation to ensure resources are released. [#18733](prometheus/prometheus#18733)
- \[BUGFIX] Scaleway SD: Resolve VPC/IPAM-only instances that have no legacy `private_ip` or `public_ip` field, but do have private NICs attached. [#18772](prometheus/prometheus#18772)
- \[BUGFIX] TSDB: Do not leak head series when an integer histogram append is rejected (e.g. out-of-order). [#18838](prometheus/prometheus#18838)
- \[BUGFIX] UI: Escape label values offered by PromQL autocomplete. [#18658](prometheus/prometheus#18658)
- \[BUGFIX] TSDB: Fix chunk snapshot encoding for EncXOR2 chunks, preventing corruption on TSDB restart when EncXOR2-encoded series were present. [#18739](prometheus/prometheus#18739)
- \[BUGFIX] TSDB: Store a millisecond timestamp (not a WAL segment number) in walExpiries when a series is evicted via CompactStaleHead/CompactSelectedSeries, so the series's label record is correctly retained in the next WAL checkpoint and replays cleanly. [#18847](prometheus/prometheus#18847)
- \[BUGFIX] TSDB: Prevent loss of samples at the chunk-range boundary when CompactSelectedSeries (and CompactStaleHead) evict the series — the per-slice compaction loop now runs one more iteration so the boundary timestamp is captured in a block before the in-memory copy is removed. [#18849](prometheus/prometheus#18849)
bboreham pushed a commit that referenced this pull request Jul 14, 2026
…changing case folds

The case-insensitive literal prefix/suffix fast paths of
FastRegexMatcher assumed that case folding preserves the encoded
length of a rune, slicing the input at len(prefix) or len(suffix)
bytes before comparing with strings.EqualFold. Unicode simple case
folding (which the regexp engine applies for case-insensitive
matching) does not guarantee that: 'k' folds with the Kelvin sign
'K' (U+212A, 3 bytes) and 's' folds with the long s 'ſ' (U+017F,
2 bytes).

As a result the fast paths cut such runes in the middle and wrongly
rejected values that the regexp itself matches, so the optimized
matcher disagreed with its own fallback regexp:

  - (?i)k.* did not match "Kelvin" (prefix pre-filter added in #18540),
  - (?i)(ka.+|kb.+) did not match "Ka" (literalPrefixInsensitiveStringMatcher, #13843),
  - .*(?i:k) did not match "abcK" (literalSuffixStringMatcher, #13843).

In a query like foo{bar=~"(?i)k.*"} this silently drops matching
series.

Replace the byte-slicing checks with fold-aware prefix/suffix
comparisons that walk runes under unicode.SimpleFold (with an ASCII
fast path processing both strings in lockstep) and return the number
of input bytes actually consumed, so the remainder handed to the
right/left sub-matchers is sliced at the correct position.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: TowyTowy <towy@airreps.link>
bboreham pushed a commit that referenced this pull request Jul 14, 2026
In #18540, the introduction of case-insensitive prefix matching caused `Prefix()`
to return case-insensitive prefixes. 
It wasn't clearly documented, but callers might expect they can call `strings.HasPrefix`
with this value, which would fail for a case-insensitive prefix.
This change returns `Prefix()` behavior to return only case-sensitive prefixes.

Signed-off-by: Casie Chen <casie.chen@grafana.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants