Observability becomes increasingly expensive as Kubernetes clusters grow.

A small cluster can collect thousands of Prometheus time series without much difficulty. At larger scale, however, histogram metrics can become a significant source of storage, memory, and query overhead. This is particularly relevant for latency metrics, where teams need detailed distributions rather than simple averages.

Kubernetes 1.37 addresses this problem by graduating native histogram support to Beta and enabling it by default. Native histograms were introduced as an Alpha feature in Kubernetes 1.36. The Kubernetes components can now expose histogram data using Prometheus Native Histogram format while retaining compatibility with classic histograms.

This creates an important migration opportunity for teams using Prometheus and Grafana:

You can begin using native histograms without immediately rewriting every existing dashboard and alert.

This article explains how native histograms work, why they improve latency observability, how Kubernetes 1.37 exposes them, how to configure Prometheus, and how to migrate existing dashboards safely.

What Is a Prometheus Histogram?

A histogram records observations such as request durations and groups them into ranges.

For example, an application might measure HTTP request latency using buckets such as:

0.005 seconds
0.010 seconds
0.025 seconds
0.050 seconds
0.100 seconds
0.250 seconds
0.500 seconds
1.000 seconds
2.500 seconds
5.000 seconds
10.000 seconds

A classic Prometheus histogram creates multiple time series for these buckets.

A simplified metric might look like:

http_request_duration_seconds_bucket{le="0.1"} 1200
http_request_duration_seconds_bucket{le="0.5"} 4800
http_request_duration_seconds_bucket{le="1"} 5200
http_request_duration_seconds_bucket{le="+Inf"} 5300

It also exposes count and sum series:

http_request_duration_seconds_count 5300
http_request_duration_seconds_sum 1420.7

This approach is well established, but it has an important limitation.

You have to decide the bucket boundaries before collecting the data.

Why Static Histogram Buckets Are a Problem

Suppose you define these buckets:

10ms
50ms
100ms
500ms
1s
5s

They might work well for an API whose normal latency is between 10ms and 500ms.

But what happens when the workload changes?

Imagine the service later handles requests ranging from 1 microsecond to 20 seconds.

The original buckets may no longer provide useful resolution.

A request completing in 100 microseconds and another completing in 40 milliseconds could end up represented in the same broad bucket.

This makes percentile calculations less precise.

Static buckets also create additional time series because every bucket is represented separately. Kubernetes documentation notes that classic histograms can create substantial storage overhead and that native histograms can reduce the number of time series associated with a histogram metric by roughly an order of magnitude.

What Are Native Histograms?

Prometheus Native Histograms use dynamic exponential bucket boundaries rather than a fixed list of manually selected buckets.

Instead of exporting a separate time series for every bucket, a native histogram stores the distribution using a compact histogram representation containing information about bucket spans and scaling.

Conceptually:

Classic Histogram

Metric
 ├── bucket 0.005
 ├── bucket 0.010
 ├── bucket 0.025
 ├── bucket 0.050
 ├── bucket 0.100
 ├── bucket 0.500
 ├── bucket 1.000
 └── bucket +Inf


Native Histogram

Metric
 └── Dynamic Exponential Distribution
       ├── Sparse Spans
       ├── Zero Threshold
       └── Scaling Schema

This allows the histogram to provide resolution across a much wider range without requiring developers to manually predict every useful latency boundary.

Why Kubernetes 1.37 Matters

Kubernetes 1.37 graduates native histogram support to Beta.

The NativeHistograms feature is enabled by default in Kubernetes 1.37. Kubernetes components can expose histogram metrics in both classic and native formats when the requested scrape protocol supports native histograms.

This affects several core components, including:

The shared Kubernetes metrics infrastructure allows histogram support to be applied consistently across these components.

This is especially useful for latency metrics such as:

apiserver_request_duration_seconds

and scheduler-related duration metrics.

Kubernetes Uses Dual Exposition

One of the most important parts of the Kubernetes 1.37 implementation is backward compatibility.

Kubernetes can expose both:

Classic Histogram
+
Native Histogram

depending on the scrape protocol and Prometheus configuration.

This means existing monitoring systems do not have to migrate everything immediately.

The architecture looks like this:

                    Kubernetes Component
                           |
                           v
                    Metrics Subsystem
                           |
              +------------+------------+
              |                         |
              v                         v
       Classic Histogram         Native Histogram
              |                         |
              v                         v
       Existing Queries          New PromQL Queries

The Kubernetes documentation describes this as dual exposition, allowing existing dashboards and alerting rules to continue working while teams migrate to native histogram queries.

Why Dual Exposition Is Important

Imagine a production Grafana dashboard containing:

histogram_quantile(
  0.99,
  rate(apiserver_request_duration_seconds_bucket[5m])
)

If the organization immediately removed all classic histogram data, that query could stop returning data.

Dual exposition provides a migration period.

You can collect:

Native Histogram
+
Classic Histogram

and gradually update your dashboards.

This is much safer than requiring a single large migration.

Kubernetes 1.37 Native Histogram Configuration

For Kubernetes 1.37, native histogram support is enabled by default.

The remaining question is whether your Prometheus installation is configured to ingest native histograms.

For Prometheus 3.x, a scrape job can be configured like this:

scrape_configs:
  - job_name: kubernetes-apiservers

    scrape_native_histograms: true

    always_scrape_classic_histograms: true

The first setting enables native histogram ingestion.

The second setting keeps classic histograms during the migration period.

Kubernetes recommends retaining classic histograms while existing dashboards and alerts are being migrated.

Prometheus Version Requirements

Native histogram support depends on the Prometheus version.

A practical compatibility view is:

Prometheus Version

Native Histogram Support

Older than 2.40

Not supported

2.40+

Native histogram support available

Prometheus 3.x

Recommended for current per-job configuration

Prometheus 3.9+

Use per-job native histogram configuration

Kubernetes documentation recommends Prometheus 3.x for current deployments because per-job configuration provides better control over native histogram ingestion.

If a monitoring stack still uses a Prometheus version older than 2.40, upgrading Prometheus should be part of the migration plan.

Prometheus Must Support the Native Exposition Protocol

Native histograms require Prometheus to negotiate an appropriate exposition format.

Prometheus uses its supported protobuf-based protocol when native histogram scraping is enabled.

If you have customized the Prometheus scrape protocol configuration, ensure that the Prometheus native histogram protocol remains available.

For example, a customized configuration should not accidentally exclude the required protocol.

The exact configuration depends on the Prometheus version and deployment method.

Classic Histogram Query

A traditional percentile query might look like:

histogram_quantile(
  0.99,
  rate(apiserver_request_duration_seconds_bucket[5m])
)

Notice the _bucket suffix.

Classic histograms require bucket series because the percentile calculation operates on those predefined boundaries.

Native Histogram Query

With native histograms, the query can operate directly on the histogram metric:

histogram_quantile(
  0.99,
  rate(apiserver_request_duration_seconds[5m])
)

The difference is subtle but important.

Classic:

metric_bucket

Native:

metric

The native histogram contains its distribution information directly.

Kubernetes documents both query styles and recommends migrating dashboard and alert expressions gradually.

Aggregating Across Multiple Kubernetes Components

Classic histogram aggregation typically requires preserving the le label.

For example:

histogram_quantile(
  0.99,
  sum by (le) (
    rate(apiserver_request_duration_seconds_bucket[5m])
  )
)

The le label identifies the bucket boundary.

With native histograms, the aggregation is simpler:

histogram_quantile(
  0.99,
  sum(
    rate(apiserver_request_duration_seconds[5m])
  )
)

There is no need to group by le because the native histogram carries its distribution information directly.

Why This Helps Latency Monitoring

Latency distributions are rarely uniform.

Consider an API where:

95% of requests → < 100ms
4%              → 100–500ms
0.9%            → 500ms–2s
0.1%            → > 2s

An average such as:

Average latency = 120ms

does not tell the whole story.

A percentile such as:

P99 = 1.8s

reveals the long tail.

For SLO-based systems, tail latency can be more important than average latency.

Native histograms provide more flexible resolution across the distribution, making them particularly useful for this kind of analysis.

Native Histograms and SLOs

Suppose your API SLO is:

99% of requests must complete within 500ms.

A classic histogram might have a bucket at:

500ms

That can work well if the bucket boundary was selected intentionally.

But if your SLO later changes to:

99.5% < 350ms

the existing bucket configuration may not provide the desired resolution.

Native histograms dynamically represent the distribution, making queries around different thresholds more flexible.

This can simplify observability for systems where SLO requirements evolve.

Kubernetes Metrics That Benefit

Kubernetes exposes many histogram metrics across its components.

Examples include:

apiserver_request_duration_seconds

and:

scheduler_plugin_execution_duration_seconds

The Kubernetes metrics reference contains the histogram metrics exposed by Kubernetes 1.37 components.

These metrics can help operators investigate:

Storage Efficiency

One of the major motivations for native histograms is reducing the number of time series required to represent distributions.

With a classic histogram:

1 Histogram
   ↓
10 buckets
   ↓
10+ related time series

With a native histogram:

1 Histogram
   ↓
Native distribution
   ↓
1 primary histogram series

The exact storage characteristics depend on the metric and data distribution, but Kubernetes documents an approximately 10x reduction in time-series count per histogram metric as a key benefit.

This can become significant in large clusters.

For example, a platform might expose hundreds of histogram metrics across:

50 API servers
+
100 scheduler/controller components
+
1,000 nodes

Even relatively small savings per histogram can become substantial at scale.

Native Histograms Do Not Mean Zero Resource Usage

It is important not to interpret storage efficiency as zero overhead.

Native histograms still require memory and computation.

Kubernetes uses bounded histogram configuration to control resource usage. The current implementation applies a maximum bucket count of 160 for histogram metrics.

Operators should therefore monitor Prometheus memory after enabling native histogram ingestion.

The correct question is not:

Do native histograms use resources?

They do.

The better question is:

Do native histograms provide better observability per unit of storage and processing cost?

For many large-scale environments, that is the more useful comparison.

Migrating an Existing Grafana Dashboard

Suppose an existing Grafana dashboard contains:

histogram_quantile(
  0.95,
  sum by (le) (
    rate(apiserver_request_duration_seconds_bucket[5m])
  )
)

Do not immediately delete the classic query.

First enable both formats:

scrape_configs:
  - job_name: kubernetes-apiservers
    scrape_native_histograms: true
    always_scrape_classic_histograms: true

Then create a new dashboard panel using:

histogram_quantile(
  0.95,
  sum(
    rate(apiserver_request_duration_seconds[5m])
  )
)

Compare the new panel against the existing one.

You should validate:

Only after the results are validated should the team consider removing classic histogram ingestion.

Migrating Alert Rules

The same principle applies to Prometheus alerts.

An existing alert might look like:

histogram_quantile(
  0.99,
  sum by (le) (
    rate(apiserver_request_duration_seconds_bucket[5m])
  )
) > 1

A native histogram version can be:

histogram_quantile(
  0.99,
  sum(
    rate(apiserver_request_duration_seconds[5m])
  )
) > 1

Do not assume that changing the query syntax is enough.

Run both versions in a staging environment and compare their behavior during:

The alert must represent the same operational condition before replacing the production rule.

Migrating Count and Sum Queries

Classic histograms commonly expose:

_metric_count
_metric_sum

Native histograms can use PromQL functions such as:

histogram_count(...)

and:

histogram_sum(...)

For example:

histogram_count(
  rate(apiserver_request_duration_seconds[5m])
)

and:

histogram_sum(
  rate(apiserver_request_duration_seconds[5m])
)

These functions allow teams to work with the native histogram representation without depending on classic _count and _sum series.

The Safest Migration Strategy

A production migration should happen in stages.

Stage 1: Upgrade Kubernetes

Move to Kubernetes 1.37 or later where native histogram support is enabled by default.

Stage 2: Verify Prometheus Compatibility

Ensure the Prometheus version supports native histograms.

Stage 3: Enable Native Histogram Scraping

Configure the relevant Prometheus jobs:

scrape_native_histograms: true
always_scrape_classic_histograms: true

Stage 4: Keep Existing Dashboards

Do not immediately modify production dashboards.

Let the classic queries continue working.

Stage 5: Build Native Queries

Create parallel panels and alerts using native histogram queries.

Stage 6: Validate

Compare the results and verify SLO behavior.

Stage 7: Migrate

Replace classic queries after validation.

Stage 8: Remove Classic Ingestion

Only after all dependencies have been migrated should you consider:

always_scrape_classic_histograms: false

This staged approach minimizes operational risk. Kubernetes specifically recommends keeping classic histogram ingestion during migration.

A Common Migration Failure

One of the easiest mistakes is configuring:

scrape_native_histograms: true
always_scrape_classic_histograms: false

while leaving an old Grafana query such as:

histogram_quantile(
  0.99,
  rate(apiserver_request_duration_seconds_bucket[5m])
)

The dashboard may suddenly show no data because the Prometheus server is ingesting native histogram data while the query still expects classic _bucket series.

Kubernetes documentation explicitly calls out this migration issue.

The safer configuration during migration is:

scrape_native_histograms: true
always_scrape_classic_histograms: true

Troubleshooting: Dashboard Shows No Data

If a dashboard stops showing latency data after native histogram configuration changes, check the query first.

If it contains:

_bucket

it is probably still using the classic format.

Then inspect the Prometheus scrape configuration.

During migration, verify:

scrape_native_histograms: true
always_scrape_classic_histograms: true

If classic ingestion was disabled accidentally, restore it while migrating the dashboard.

Troubleshooting: Prometheus Does Not Understand Native Histograms

If Prometheus reports an unknown or unsupported histogram format, verify the Prometheus version.

Native histogram support requires Prometheus 2.40 or later.

For older Prometheus deployments:

Upgrade Prometheus
        or
Disable Native Histogram Ingestion

Upgrading is generally preferable if the organization wants to take advantage of the newer observability model.

Troubleshooting: Memory Usage Increases

Native histograms can change the memory profile of the Prometheus server.

Monitor Prometheus resource usage after enabling ingestion.

Useful signals include:

process_resident_memory_bytes

and the Prometheus server's normal TSDB and scrape health metrics.

If memory pressure becomes significant, reduce the scope of native histogram ingestion or temporarily disable it for affected jobs.

Kubernetes documents that its histogram configuration limits the number of buckets to control memory usage.

Troubleshooting: Native Histograms Are Not Being Exposed

First verify the Kubernetes feature gate:

kubernetes_feature_enabled{
  name="NativeHistograms"
}

A value of:

1

indicates that the feature is enabled for the relevant component.

You can also inspect the component's /metrics endpoint using the appropriate Prometheus protobuf Accept header.

This is mainly useful for troubleshooting rather than routine monitoring.

Classic vs. Native Histograms

Feature

Classic Histogram

Native Histogram

Bucket boundaries

Static

Exponential/dynamic

Bucket configuration

Manual

Automatically structured

Time-series count

Higher

Lower

Quantile resolution

Depends on bucket design

More consistent across ranges

Existing dashboard compatibility

Excellent

Requires native query support

Migration effort

None for existing systems

Requires query migration

Storage efficiency

Lower

Higher

Best use case

Mature existing dashboards

High-scale, high-resolution observability

Neither format needs to be treated as universally superior.

Classic histograms remain useful and are still supported.

Native histograms are an additional representation that addresses several limitations of fixed buckets.

Advantages of Kubernetes 1.37 Native Histograms

Better Latency Resolution

Dynamic exponential buckets provide more useful resolution across a broad range of observations.

Lower Time-Series Overhead

Native histograms can substantially reduce the number of time series required for histogram metrics.

Easier Quantile Queries

Native PromQL queries operate directly on histogram metrics.

Better Long-Tail Visibility

Latency distributions can be represented more effectively without requiring a large manually designed bucket list.

Gradual Migration

Dual exposition allows existing dashboards and alerts to continue working during migration.

Kubernetes-Wide Integration

The feature is implemented in the common metrics infrastructure and is available across major Kubernetes components.

Disadvantages and Considerations

Prometheus Compatibility

Older Prometheus versions cannot ingest native histograms.

Dashboard Migration

Existing _bucket queries need to be migrated if teams want to stop ingesting classic histograms.

Operational Complexity

Running both formats temporarily increases observability configuration complexity.

Resource Consumption

Native histograms still consume memory and processing resources.

Tooling Compatibility

Every component between Kubernetes and the final visualization or storage system must correctly support native histogram data.

Migration Risk

Removing classic histograms too early can break dashboards and alerts.

Best Practices

Keep Classic Histograms During Migration

Use:

scrape_native_histograms: true
always_scrape_classic_histograms: true

until existing queries have been migrated.

Migrate Queries Incrementally

Do not rewrite hundreds of dashboards in one deployment.

Start with a small set of high-value latency dashboards.

Test Alerts Separately

A dashboard can look correct while an alert expression still has an issue.

Validate SLOs

Compare percentile behavior around actual service-level objectives.

Monitor Prometheus Resources

Observe memory, ingestion, query latency, and storage behavior after enabling native histogram ingestion.

Upgrade Prometheus Before Kubernetes Migration

Kubernetes 1.37 can expose native histograms, but your monitoring system must be capable of consuming them.

Maintain a Rollback Plan

If native histogram ingestion causes unexpected issues, Prometheus 3.x can disable native histogram scraping per job without restarting the Kubernetes component.

When Should You Keep Classic Histograms?

Not every organization needs to immediately eliminate classic histograms.

Keeping classic histograms can make sense when:

Kubernetes 1.37's dual-exposition design allows this transition.

When Should You Adopt Native Histograms?

Native histograms become especially attractive when:

The larger the monitoring environment, the more valuable efficient histogram representation can become.

A Production Migration Checklist

Before enabling native histogram ingestion across production, verify:

[ ] Kubernetes is running 1.37+
[ ] Prometheus supports native histograms
[ ] Prometheus scrape configuration is updated
[ ] Native histogram ingestion works in staging
[ ] Classic histogram ingestion remains enabled
[ ] Existing dashboards still return data
[ ] Native queries have been tested
[ ] SLO queries have been validated
[ ] Alert rules have been tested
[ ] Grafana panels have been migrated where appropriate
[ ] Prometheus memory usage is monitored
[ ] Rollback configuration is documented

Only after these checks pass should you consider removing classic histogram ingestion.

Conclusion

Kubernetes 1.37 makes native histograms a practical next step for Prometheus-based observability.

The most important improvement is not simply that Kubernetes can expose another metric format. Native histograms address fundamental limitations of classic histograms by using dynamically structured exponential buckets, reducing time-series overhead and providing more flexible visibility into latency distributions.

The migration does not have to be disruptive.

A safe approach is:

Kubernetes 1.37
      |
      v
Enable Native Histogram Scraping
      |
      +-------------------+
      |                   |
      v                   v
Classic Histograms    Native Histograms
      |                   |
      v                   v
Existing Dashboards    New Queries
      |                   |
      +---------+---------+
                |
                v
          Validate Alerts
                |
                v
       Migrate Dashboards
                |
                v
      Disable Classic Format
        When Ready

For teams operating large Kubernetes environments, native histograms can provide a better balance between latency accuracy, query flexibility, and observability storage efficiency.

The key is to treat Kubernetes 1.37 as the beginning of a controlled observability migration rather than a reason to immediately replace every existing Prometheus query.