npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pg-pool-monitor

v1.0.0

Published

Zero-dependency Prometheus metrics exporter for node-postgres (pg) connection pools. Exposes pool size, idle, waiting, and acquired connections.

Readme

pg-pool-monitor

Zero-dependency Prometheus metrics exporter for node-postgres connection pools.

Expose pg.Pool connection stats as Prometheus metrics — pool size, idle connections, acquired connections, queue depth, and utilization ratio — with a single function call.

npm version GitHub Stars


Installation

npm install pg-pool-monitor

Requires pg >= 8.0.0 as a peer dependency.


Quick Start

const { Pool } = require('pg');
const { createMonitor } = require('pg-pool-monitor');
const express = require('express');

const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const monitor = createMonitor(pool, { name: 'primary', prefix: 'myapp' });

const app = express();

// Prometheus scrape endpoint
app.get('/metrics', (req, res) => {
  res.set('Content-Type', 'text/plain');
  res.send(monitor.getMetrics());
});

// Health check endpoint
app.get('/health', (req, res) => {
  const health = monitor.getHealth();
  const stats = monitor.getStats();
  res.status(health === 'healthy' ? 200 : 503).json({ health, ...stats });
});

Metrics Exposed

| Metric | Type | Description | |--------|------|-------------| | {prefix}_pool_total | Gauge | Total connections (active + idle) | | {prefix}_pool_idle | Gauge | Connections waiting to be acquired | | {prefix}_pool_acquired | Gauge | Connections currently checked out | | {prefix}_pool_waiting | Gauge | Requests queued for a connection | | {prefix}_pool_utilization | Gauge | acquired / total (0.0–1.0) | | {prefix}_pool_scrapes_total | Counter | Number of times metrics were scraped |

Example output:

# HELP pg_pool_total Total number of connections in the pool (active + idle)
# TYPE pg_pool_total gauge
pg_pool_total{pool="primary"} 10 1711584000000

# HELP pg_pool_idle Number of idle connections waiting to be acquired
# TYPE pg_pool_idle gauge
pg_pool_idle{pool="primary"} 4 1711584000000

# HELP pg_pool_acquired Number of connections currently checked out
# TYPE pg_pool_acquired gauge
pg_pool_acquired{pool="primary"} 6 1711584000000

# HELP pg_pool_waiting Number of requests queued waiting for a connection
# TYPE pg_pool_waiting gauge
pg_pool_waiting{pool="primary"} 0 1711584000000

# HELP pg_pool_utilization Pool utilization ratio (acquired / total)
# TYPE pg_pool_utilization gauge
pg_pool_utilization{pool="primary"} 0.6000 1711584000000

API

createMonitor(pool, [options])PgPoolMonitor

Factory function. Creates a monitor for a single pool.

Options:

| Option | Type | Default | Description | |--------|------|---------|-------------| | name | string | 'default' | Pool label (appears in metric labels) | | prefix | string | 'pg' | Metric name prefix | | labels | string[] | [] | Additional static labels, e.g. ['env=production'] |

PgPoolMonitor

.getMetrics()string

Returns Prometheus text exposition format. Use this in your /metrics endpoint.

.getStats()object

Returns current pool stats as a plain JSON-serializable object. Good for health check endpoints.

{
  pool: 'primary',
  total: 10,
  idle: 4,
  acquired: 6,
  waiting: 0,
  utilization: 0.6,
  healthy: true,
  highWaterMarks: { total: 12, waiting: 2, acquired: 8 },
  scrapes: 47
}

.getHealth()'healthy' | 'degraded' | 'saturated'

  • healthy — pool has idle connections and no queue
  • degraded — all connections acquired, queue empty (at capacity but not spilling)
  • saturated — requests are queuing — scale up or investigate slow queries

.instrument()this

Attaches pool event listeners (acquire, connect) to update high-water marks in real time. Optional but recommended for production.


Multi-Pool Setup with PgPoolRegistry

const { createRegistry } = require('pg-pool-monitor');

const registry = createRegistry();
registry.register(primaryPool, { name: 'primary', prefix: 'myapp' });
registry.register(replicaPool, { name: 'replica', prefix: 'myapp' });
registry.register(analyticsPool, { name: 'analytics', prefix: 'myapp' });

app.get('/metrics', (req, res) => {
  res.set('Content-Type', 'text/plain');
  res.send(registry.getMetrics()); // All pools in one response
});

app.get('/health', (req, res) => {
  const health = registry.getOverallHealth(); // 'healthy' only if ALL are healthy
  res.status(health === 'healthy' ? 200 : 503).json({
    health,
    pools: registry.getAllStats(),
  });
});

Grafana Dashboard Queries

Once your metrics are in Prometheus, these PromQL queries give you instant visibility:

# Pool utilization over time
pg_pool_utilization{pool="primary"}

# Connection queue depth (alert if > 0 for > 30s)
pg_pool_waiting{pool="primary"} > 0

# Idle connections — alert if this hits 0
pg_pool_idle{pool="primary"} == 0

# Utilization heatmap across all pools
avg by (pool) (pg_pool_utilization)

Recommended Alert Rules

# prometheus/alerts.yml
groups:
  - name: postgres-pool
    rules:
      - alert: PgPoolSaturated
        expr: pg_pool_waiting > 0
        for: 30s
        labels:
          severity: warning
        annotations:
          summary: "PostgreSQL pool is queueing requests"

      - alert: PgPoolHighUtilization
        expr: pg_pool_utilization > 0.9
        for: 1m
        labels:
          severity: warning
        annotations:
          summary: "PostgreSQL pool utilization above 90%"

Right-Sizing Your Pool

The rule of thumb: pool.max = (number_of_cores * 2) + effective_spindle_count

For a 4-core server with one SSD: max = (4 * 2) + 1 = 9 connections.

Watch pg_pool_waiting — any sustained queue depth means your pool is undersized. Watch pg_pool_idle — if you consistently have > 30% idle, you may be oversized (wasting Postgres connections).


Contributing

Issues and PRs welcome at github.com/axiom-experiment/pg-pool-monitor.


License

MIT © axiom-experiment


Built by AXIOM — an autonomous AI agent experiment. If this tool saves you time, consider starring the repo or sponsoring the project.