mrkeyoor.com_
Sun 20 Sept 07:01 UTC
PyPIInfraupdated 19 Sept 2026

prometheus-client review

prometheus-client 0.26.0 is the official Python instrumentation package for exporting Prometheus and OpenMetrics data. Counter, Gauge, Histogram, Summary, Info, and Enum objects register samples that can be served over HTTP, mounted in WSGI or ASGI, written for node_exporter, or sent to a Pushgateway. Version 0.26 makes Timer context duration readable, adds TLS-version controls to the WSGI server, validates Enum states before collector registration, and fixes duplicate-series errors, exemplars, native histogram sums, and collector unregister behavior.

Verdict

prometheus-client 0.26.0 installed in 0.3 seconds and used 1 MB in our sandbox, making package cost negligible compared with the label and multiprocess design work. Install it for Prometheus-native Python metrics, but walk away when cardinality is uncontrolled or a prefork deployment cannot manage shared metric files.

We installed it

Lab card: what happened when we installed prometheus-clientScreenshot of prometheus-client documentation
Install✓ · 0.3s1 package on disk · 1 MB
Importimport prometheus_client in 0.30s · pure Python · py.typed · requires Python >=3.9
Known vulns0(pip-audit)

Answers from our run

Does prometheus-client install cleanly?

Yes. In a fresh container with an empty cache, pip install prometheus-client finished in 0.3s, leaving 1 package and 1 MB on disk. pip-audit reported no known vulnerabilities.

What does prometheus-client need to run?

Python >=3.9, and nothing compiled: it is pure Python. In our run import prometheus_client succeeded in 0.30s, and the package ships py.typed for type checkers.

prometheus-client or opentelemetry-api: which should you use?

Pick opentelemetry-api when opentelemetry-api 1.x fits when one vendor-neutral API should cover metrics and distributed tracing. prometheus-client 0.26.0 installed in 0.3 seconds and used 1 MB in our sandbox, making package cost negligible compared with the label and multiprocess design work.

When should you not use prometheus-client?

A prefork deployment cannot create and clear PROMETHEUS_MULTIPROC_DIR or mark dead workers. Normal in-memory registries do not merge themselves across processes.

API stability5/5Counter, Gauge, Histogram, Summary, labels(), inc(), observe(), time(), CollectorRegistry, generate_latest(), and HTTP exposition have stable, direct call shapes. Version 0.26 adds Timer.duration and tighter Enum validation without changing ordinary metric declarations. Multiprocess and collector internals carry more constraints, so applications using custom collectors, exemplars, or process files should test patch upgrades against emitted text.
Docs5/5The official documentation covers every metric type, labels, exemplars, custom collectors, parsers, WSGI, ASGI, HTTP servers, TLS, Pushgateway, node_exporter textfiles, multiprocess mode, and framework integrations. Its multiprocess page lists unsupported features and required lifecycle hooks. The quick examples are easy to copy, although production readers must still design buckets, cardinality limits, endpoint protection, and metric ownership themselves.
Maintenance5/5PyPI and GitHub released 0.26.0 on July 24, 2026, and the repository was pushed on August 13, 2026. GitHub shows 4,361 stars, 149 open issues and pull requests, and an unarchived repository under the Prometheus organization. The release fixes duplicate time series, native histogram parsing, exemplar validation, and registry cleanup while adding WSGI TLS controls, all directly relevant to emitted metrics.
Ecosystem5/5The supplied package data estimates 39,605,174 weekly downloads, and GitHub reports 4,361 stars. Prometheus scrapers, OpenMetrics tooling, Grafana dashboards, alert rules, Kubernetes monitoring, node_exporter textfiles, and many Python frameworks already understand its exposition format. Interoperability is broad, but a service standardized on OpenTelemetry may prefer one instrumentation layer and export Prometheus data from that pipeline.

Use it if

  • prometheus-client 0.26.0 fits a Python service whose metrics will be scraped by Prometheus or an OpenMetrics-compatible collector.
  • Request counts and latency distributions need explicit labels and Histogram buckets owned by application code.
  • A batch process can publish through node_exporter's textfile collector or a deliberately managed Pushgateway group.
  • The deployment can follow the package's separate multiprocess setup for Gunicorn or another prefork server.
Skip it if

Setup reality

We installed prometheus-client 0.26.0 in a fresh Python 3.12 Bookworm sandbox. The install completed in 0.3 seconds, left 1 package, and used 1 MB. pip-audit found 0 known vulnerabilities. Package metadata reports 3 direct dependencies, Python >=3.9, and pure Python code. import prometheus_client worked in 0.30 seconds. The distribution includes py.typed, while the measured license field was unknown.

Metric names enter the default registry at import time in many applications. Importing the same module through two paths or recreating a metric with the same name raises a duplicate-series error. Tests are easier with a private CollectorRegistry. Labels are schema, not decoration: every label must be supplied, and every distinct combination persists as a series. Use route templates and bounded status or operation values.

start_http_server opens a metrics endpoint in its own thread; make_asgi_app and make_wsgi_app mount exposition inside an application. Neither adds authentication. Bind to a private interface, protect the route at the proxy, or let an in-host agent scrape it. Histograms require buckets chosen for the service's latency or size range. Version 0.26 exposes a Timer context's measured duration, but it does not repair poor buckets.

Multiprocess mode writes per-process metric files under PROMETHEUS_MULTIPROC_DIR. Set that variable before Python imports the client, clear the directory between deployments, collect through MultiProcessCollector, and call mark_process_dead from the worker-exit hook. Several features have multiprocess limits, including custom collectors and some Gauge behavior. Pushgateway values also outlive the process, so jobs need stable grouping keys and an explicit deletion policy.

Patterns

Count requests with bounded labels count-requests

from prometheus_client import Counter

REQUESTS = Counter('app_requests_total', 'Completed requests', ['method', 'route', 'status'])
REQUESTS.labels('GET', '/items/{id}', '200').inc()

Use /items/{id}, not the raw URL. Object IDs would create one time series per item.

Observe latency in chosen buckets time-operation

from prometheus_client import Histogram

LATENCY = Histogram('app_job_duration_seconds', 'Job duration', ['kind'], buckets=(0.1, 0.5, 1, 2.5, 5, 10))
with LATENCY.labels('import').time() as timer:
    import_rows()
print(timer.duration)

Version 0.26 exposes timer.duration after the context exits. PromQL quantile usefulness still depends on these bucket boundaries.

Track active work through exceptions track-in-progress

from prometheus_client import Gauge

ACTIVE = Gauge('app_tasks_in_progress', 'Tasks currently running')
with ACTIVE.track_inprogress():
    run_task()

The context decrements the Gauge when run_task raises, preventing an exception from leaving a false active count.

Serve metrics on loopback serve-metrics

from prometheus_client import start_http_server

server, thread = start_http_server(8000, addr='127.0.0.1')
run_worker()

The endpoint has no built-in authentication. Loopback is suitable when a local agent performs the scrape.

Mount an ASGI metrics route mount-asgi

from fastapi import FastAPI
from prometheus_client import make_asgi_app

app = FastAPI()
app.mount('/metrics', make_asgi_app())

Several application workers need multiprocess mode; separate in-memory registries otherwise expose per-worker values.

Test with an isolated registry test-registry

from prometheus_client import CollectorRegistry, Counter

registry = CollectorRegistry()
failures = Counter('app_failures_total', 'Failed operations', ['kind'], registry=registry)
failures.labels('timeout').inc()
assert registry.get_sample_value('app_failures_total', {'kind': 'timeout'}) == 1.0

A private registry prevents module-level metrics from colliding across tests or import order.

Publish one batch result atomically write-textfile

from prometheus_client import CollectorRegistry, Gauge, write_to_textfile

registry = CollectorRegistry()
last_success = Gauge('batch_last_success_timestamp_seconds', 'Last success', registry=registry)
last_success.set_to_current_time()
write_to_textfile('/var/lib/node_exporter/textfile_collector/import.prom', registry)

The path must be inside node_exporter's configured textfile directory. A temporary file plus rename replaces the output atomically.

Merge prefork worker metric files collect-multiprocess

from prometheus_client import CollectorRegistry, generate_latest, multiprocess

def render_metrics():
    registry = CollectorRegistry()
    multiprocess.MultiProcessCollector(registry)
    return generate_latest(registry)

PROMETHEUS_MULTIPROC_DIR must exist before client import and be cleared for each deployment. Mark worker pids dead on exit.

Alternatives

PackageRegistryPick it when
opentelemetry-apiPyPIopentelemetry-api 1.x fits when one vendor-neutral API should cover metrics and distributed tracing.
statsdPyPIUse statsd for fire-and-forget UDP metrics to an existing StatsD-compatible agent.
datadogPyPIUse the Datadog client when the deployment is committed to Datadog APIs and agent conventions rather than Prometheus exposition.

More infra guides

boto3 · opentelemetry-api · psutil · distro · @opentelemetry/api · google-cloud-storage · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.