Skip to content

Optimize labels() existing-child lookups to avoid parent lock contention #1215

Description

@baruch321-code

Summary

Consider avoiding acquisition of the parent metric's _lock in MetricWrapperBase.labels() when the requested labeled child already exists, while retaining synchronized child creation.

Current behavior

In [prometheus_client/metrics.py, lines 173–203
labels() validates and normalizes label values, then acquires self._lock before checking _metrics. Consequently, repeated lookups of existing children all acquire the same parent lock, including lookups for different labelsets.

`with self._lock:

  if str_labelvalues not in self._metrics:

      ...
      CREATE METRIC

  return self._metrics[str_labelvalues]           

`

In high-contention multithreaded instrumentation that repeatedly calls metric.labels(...).inc() or .observe() for already initialized labelsets, this is a potential source of avoidable synchronization overhead. No benchmark results are supplied, so the magnitude of any improvement remains to be measured.

Proposed approach

  • Preserve all existing label validation and normalization.
  • Attempt a single dictionary lookup for the existing child before acquiring the parent lock, with a missing-key fallback.
  • On a miss, acquire self._lock and recheck _metrics before constructing and storing a child, preserving the existing constructor arguments and behavior.
  • Keep creation and mutation synchronized. This proposal only avoids the explicit parent lock on lookup hits; it does not imply that dictionary internals or subsequent metric updates are lock-free.

`
if metric := self._metrics.get(str_labelvalues):

 return metric

with self._lock:

  if str_labelvalues not in self._metrics:

      ...

      CREATE METRIC

  return self._metrics[str_labelvalues]           

`

Duplicate search

No matching open issue was found in searches of this repository for labels locking, contention, and labels performance.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions