Skip to content

LabelNamer.Build() causes memory fragmentation with frequent label transformations #68

@leiwingqueen

Description

@leiwingqueen

Description

LabelNamer.Build() allocates a new string on every call, even when the label name is already compliant. This causes significant memory fragmentation, especially in high-frequency label transformation
scenarios (e.g., OpenTelemetry Collector Contrib's Prometheus remote write exporter).

Steps to Reproduce

  1. Use OpenTelemetry Collector to collect a large number of metrics
  2. Observe significant memory fragmentation in the process

Analysis

Current Build() implementation:

normalizedName := sanitizeLabelName(label, ln.PreserveMultipleUnderscores)

sanitizeLabelName uses strings.Builder internally to create a new string on every call:

  • Allocates new memory
  • Copies the entire label string
  • Returns a new string

Expected Behavior

For already-compliant labels (e.g., http_method), should:

  1. Return the original string directly without allocation
  2. Or reuse cached transformation results

Reference Implementation

VictoriaMetrics' FastStringTransformer uses sync.Map to cache transformation results, avoiding repeated allocations.

Environment

  • OpenTelemetry Collector Contrib
  • Prometheus remote write exporter
  • High-cardinality metrics scenario

Related Components

  • LabelNamer.Build()
  • sanitizeLabelName()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions