{"id":16180,"library":"prom-client","title":"Prometheus Client for Node.js","description":"Prometheus client for Node.js (`prom-client`) is a comprehensive toolkit for instrumenting Node.js applications with Prometheus metrics. It supports all standard Prometheus metric types including counters, gauges, histograms, and summaries, alongside OpenMetrics and Exemplars which were introduced in version 15.0.0. The package is currently stable at version 15.1.3, with a release cadence that sees frequent patch and minor updates addressing bugs and adding features, while major versions are released less often to accommodate significant changes like Node.js version support adjustments and new Prometheus protocol features. Key differentiators include its robust support for Node.js `cluster` module aggregation, providing sensible defaults for common metrics, and a rich set of built-in 'default metrics' for runtime performance and resource usage. It ships with TypeScript types, enabling strong typing for metric definitions and interactions.","status":"active","version":"15.1.3","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/siimon/prom-client","tags":["javascript","Prometheus","Metrics","Client","typescript"],"install":[{"cmd":"npm install prom-client","lang":"bash","label":"npm"},{"cmd":"yarn add prom-client","lang":"bash","label":"yarn"},{"cmd":"pnpm add prom-client","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The common practice is to import named exports. While CJS require works, ES module imports are preferred in modern Node.js development.","wrong":"const Registry = require('prom-client').Registry;","symbol":"Registry","correct":"import { Registry } from 'prom-client';"},{"note":"`collectDefaultMetrics` is a named export, not the default export.","wrong":"import collectDefaultMetrics from 'prom-client';","symbol":"collectDefaultMetrics","correct":"import { collectDefaultMetrics } from 'prom-client';"},{"note":"Metric types (Counter, Gauge, Histogram, Summary) are named exports and should be imported directly.","wrong":"const Counter = require('prom-client').Counter;","symbol":"Counter","correct":"import { Counter } from 'prom-client';"}],"quickstart":{"code":"import express from 'express';\nimport { collectDefaultMetrics, Registry, Counter } from 'prom-client';\n\nconst app = express();\nconst port = process.env.PORT || 3000;\n\n// Create a new registry to register custom metrics\nconst register = new Registry();\n\n// Collect default metrics like CPU, memory, event loop lag, etc.\n// These are registered to the custom 'register' instance.\ncollectDefaultMetrics({\n  register: register,\n  prefix: 'my_app_',\n  labels: { APP_NAME: 'my_service' }\n});\n\n// Create a custom counter metric\nconst httpRequestCounter = new Counter({\n  name: 'my_app_http_requests_total',\n  help: 'Total number of HTTP requests',\n  labelNames: ['method', 'route', 'status'],\n  registers: [register]\n});\n\n// Example route to increment the counter\napp.get('/', (req, res) => {\n  httpRequestCounter.inc({ method: 'GET', route: '/', status: 200 });\n  res.send('Hello World!');\n});\n\n// Expose metrics at the /metrics endpoint\napp.get('/metrics', async (req, res) => {\n  res.set('Content-Type', register.contentType);\n  res.end(await register.metrics());\n});\n\napp.listen(port, () => {\n  console.log(`Server listening at http://localhost:${port}`);\n  console.log(`Metrics available at http://localhost:${port}/metrics`);\n});","lang":"typescript","description":"This quickstart demonstrates how to set up an Express.js server, collect default Node.js metrics, define a custom counter, and expose them on a /metrics endpoint, all using a dedicated Prometheus registry."},"warnings":[{"fix":"Upgrade your Node.js runtime to version 16, 18, or 20 (or higher) to use `prom-client` v15+ features and bug fixes. Alternatively, pin `prom-client` to a 14.x version.","message":"Version 15.0.0 dropped support for Node.js versions 10, 12, 14, 17, and 19. Applications on these older Node.js versions must upgrade their Node.js runtime or stay on a `prom-client` version below 15.0.0.","severity":"breaking","affected_versions":">=15.0.0"},{"fix":"Implement the `AggregatorRegistry` pattern as shown in the `example/cluster.js` to aggregate metrics across workers. For custom metrics, set the `aggregator` property (e.g., 'sum', 'first', 'min', 'max', 'average', 'omit') in the metric config.","message":"When using Node.js's `cluster` module, individual worker metrics will not provide a complete view. Metrics need to be aggregated from all workers in the master process to get accurate global metrics. Custom metrics require configuring the `aggregator` property for correct aggregation.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Be aware of platform limitations when relying on specific system-level default metrics. Consider custom metrics or external node exporters for cross-platform system metrics if strict parity is required.","message":"Some default metrics, specifically those concerning File Descriptors and Memory details, are only available on Linux operating systems. On other platforms (e.g., macOS, Windows), these metrics will not be collected or exposed.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure label names are valid Prometheus identifiers (e.g., `[a-zA-Z_:][a-zA-Z0-9_:]*`). Verify that label values are correctly supplied and that you are not accidentally creating an unbounded number of label combinations (high cardinality).","message":"Incorrectly formatted or non-unique labels can lead to errors during metric creation or observation. Labels must adhere to Prometheus naming conventions, and each unique combination of labels for a given metric should ideally represent a distinct series.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure your Prometheus server or scraping agent is configured to accept OpenMetrics format if you are leveraging Exemplars or the new format features. Use `Registry.PROMETHEUS_CONTENT_TYPE` or `Registry.OPENMETRICS_CONTENT_TYPE` for setting the `Content-Type` header appropriately.","message":"Version 15.0.0 introduced support for OpenMetrics and Exemplars. While this adds powerful new capabilities, consuming Prometheus servers or scrapers must be compatible with OpenMetrics format if these features are used. The `contentType` constant was also adjusted for these formats in v15.1.2.","severity":"breaking","affected_versions":">=15.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure each metric has a unique name within a given `Registry` instance. If you intend to use a single global metric, define it once and reuse the instance. If using multiple registries, ensure the metric is only registered to its intended registry.","cause":"Attempting to register a metric with a name that is already in use by another metric within the same registry.","error":"Error: A metric with the name 'my_metric_name' has already been registered."},{"fix":"Verify that the metric object is correctly instantiated and assigned before any operations are performed on it. This often happens if a metric is defined conditionally or in a scope where it's not accessible.","cause":"Attempting to interact with a metric (e.g., `inc()`, `set()`) before it has been properly initialized or if the variable holding the metric instance is `undefined`.","error":"TypeError: Cannot read properties of undefined (reading 'inc')"},{"fix":"Review the `labelNames` array provided in the metric constructor and remove any duplicate label names. Each label name must be unique.","cause":"When defining a metric with `labelNames`, providing duplicate names in the array.","error":"Error: Labels are not unique."},{"fix":"Ensure all labels specified in the `labelNames` array during metric definition are provided when observing the metric, with exact matching keys. For example, if `labelNames: ['method']` then call `inc({ method: 'GET' })`.","cause":"When observing a metric (e.g., `inc()`, `set()`), required labels defined in `labelNames` were omitted or misspelled.","error":"Error: Missing label 'method' on metric 'my_app_http_requests_total'"}],"ecosystem":"npm"}