Skip to content
Telemetry
Integration guide

node-postgres Pool and Query Telemetry

Instrument node-postgres query fingerprints, connection acquisition, pool pressure, timeouts, transaction outcomes, and database errors without logging SQL parameters.

Reviewed by the Telemetry product team on . Instrumentation contract, privacy boundaries, and implementation guidance. Review standards and ownership

Useful for
  • Postgres connection-pool monitoring
  • Slow database operation analysis
  • Transaction and timeout debugging
Implementation evidence

node-postgres Pool and Query Telemetry: from boundary to verified row

Use node-postgres Pool and Query Telemetry at a controlled application boundary, keep the event contract small, and verify a known outcome before building aggregate views.

  1. 1

    Choose the outcome

    Postgres connection-pool monitoring

  2. 2

    Define the contract

    query_fingerprint, service, database_name, status, and duration_ms

  3. 3

    Instrument the boundary

    Pass a bounded fingerprint from the call site instead of deriving it from raw SQL.

  4. 4

    Verify the evidence

    Exercise a known fixture, then inspect database_query_completed for one correctly typed terminal row.

Before you start

Prerequisites and boundaries

  • The pg package with a shared Pool
  • Application-owned operation fingerprints
  • A server-side TELEMETRY_API_KEY

Delivery setup

Install and initialize server-side

Import telemetry-sh in server-only code and initialize it once with process.env.TELEMETRY_API_KEY. Keep ingestion credentials out of browser bundles, client-visible environment variables, source control, logs, and exception messages.

node-postgres-install

npm installation

bash
npm install telemetry-sh
  1. 1Prepare one reusable server-side delivery client with bounded network behavior.
  2. 2Add the outcome event at the success, failure, retry, or timeout boundary.
  3. 3Send controlled fixtures and inspect the stored rows before enabling an alert.

Snippet

Start with one structured event

Add this shape where the workflow completes, fails, or retries. Then build the dashboard from real fields.

node-postgres

node-postgres Pool and Query Telemetry event

javascript
import { Pool } from "pg";
import telemetry from "telemetry-sh";

const pool = new Pool({ max: 10 });
const SAFE_DATABASE_ERROR_CODES = new Set(["40001", "40P01", "55P03", "57014"]);

function classifyDatabaseError(error) {
  return error && typeof error === "object" &&
    "code" in error &&
    SAFE_DATABASE_ERROR_CODES.has(String(error.code))
    ? String(error.code)
    : "database_error";
}

async function runDatabaseOperation({
  queryFingerprint,
  text,
  values,
}) {
  const acquireStartedAt = performance.now();
  let client;

  try {
    client = await pool.connect();
    const acquisitionWaitMs = performance.now() - acquireStartedAt;
    const queryStartedAt = performance.now();
    const result = await client.query(text, values);
    await telemetry.log("database_query_completed", {
      query_fingerprint: queryFingerprint,
      service: "checkout-api",
      database_name: "app_production",
      status: "success",
      duration_ms: Math.round(performance.now() - queryStartedAt),
      acquisition_wait_ms: Math.round(acquisitionWaitMs),
      rows_returned: result.rowCount ?? result.rows.length,
      active_connections: pool.totalCount - pool.idleCount,
      idle_connections: pool.idleCount,
      max_connections: pool.options.max ?? 10,
      waiting_count: pool.waitingCount,
      release: process.env.APP_RELEASE,
      environment: process.env.NODE_ENV,
    });
    return result;
  } catch (error) {
    await telemetry.log("database_query_completed", {
      query_fingerprint: queryFingerprint,
      service: "checkout-api",
      database_name: "app_production",
      status: "failed",
      duration_ms: Math.round(performance.now() - acquireStartedAt),
      error_type: classifyDatabaseError(error),
      active_connections: pool.totalCount - pool.idleCount,
      idle_connections: pool.idleCount,
      max_connections: pool.options.max ?? 10,
      waiting_count: pool.waitingCount,
      release: process.env.APP_RELEASE,
      environment: process.env.NODE_ENV,
    });
    throw error;
  } finally {
    client?.release();
  }
}

Event contract

query_fingerprint, service, database_name, status, and duration_ms

active_connections, idle_connections, max_connections, and waiting_count

acquisition_wait_ms, rows_returned, error_type, release, and environment

Implementation checkpoints

Checkpoint 1

Pass a bounded fingerprint from the call site instead of deriving it from raw SQL.

Checkpoint 2

Measure connection acquisition separately from query execution so pool contention is not mistaken for database work.

Checkpoint 3

Record driver error codes through an allowlist and never forward connection strings, query parameters, or raw database messages.

Verification

Prove the event arrived

Run this after exercising known success and failure cases. Replace the fallback table name if your final event contract differs from the snippet.

node-postgres-verification

node-postgres Pool and Query Telemetry verification query

sql
SELECT *
FROM database_query_completed
ORDER BY timestamp_utc DESC
LIMIT 20;
Confirm one terminal row per logical outcome, with the expected status, identifiers, units, and UTC time.
Inspect the inferred schema and verify that retries do not change field types or generate a new logical event ID.
Search the stored fields for credentials, raw payloads, prompts, private content, and unbounded error messages.
Exercise a provider timeout, ingestion rejection, and process shutdown before treating the dashboard as complete.

Implementation references

Review the event contract, data-safety guidance, and upstream primary documentation before enabling a new production path.

Production boundary

Keep the outcome event small and recoverable

This pattern provides

  • A bounded, SQL-ready outcome beside the upstream workflow.
  • Stable fields for dashboards, alerts, and cross-event correlation.
  • A fixture-driven path for validating success, failure, retry, and timeout behavior.

This pattern does not provide

  • An OTLP exporter, automatic collection pipeline, or replacement for detailed traces and diagnostic logs.
  • Exactly-once delivery merely because the payload contains an event ID.
  • Permission to collect raw provider payloads, user content, credentials, or regulated data.

Event schema starting points

Review the row grain, emit boundary, required types, privacy classes, example payload, and validation checklist before adapting a query or snippet to production.

Related product capability

Continue this workflow in SQL query API

Run read-only DataFusion SQL over structured-event tables and reuse the result.

Related SQL recipes

Answer the next question with SQL

Run the query against the structured fields from this workflow, inspect the example result, and turn a useful answer into a dashboard or alert.

Browse all recipes
Database reliabilityBeginner

Find Slow Database Queries by Fingerprint

Which database operations are consistently slow enough to investigate?

Open recipe
Database reliabilityBeginner

Rank Database Queries by Total Time Impact

Which database operation consumes the most cumulative request time?

Open recipe
Database reliabilityBeginner

Measure Database Connection-Pool Saturation

Which application pools are making callers wait for a database connection?

Open recipe
Database reliabilityIntermediate

Measure Database Connection Timeouts and Churn

Which services and regions show unhealthy database connection churn?

Open recipe
Database reliabilityIntermediate

Calculate Database Transaction Rollback Rate

Which services roll back an unusual share of database transactions?

Open recipe
Database reliabilityIntermediate

Measure Long-Running Database Transactions

Which application transaction classes remain open the longest?

Open recipe
Database reliabilityIntermediate

Find Database Lock Waits and Deadlocks

Which database operations create the most serious lock contention?

Open recipe
Database reliabilityBeginner

Analyze Database Errors by SQLSTATE and Release

Which database error classes increased after an application release?

Open recipe
Database reliabilityBeginner

Measure Database Replication and CDC Lag

Which replicas or CDC consumers are falling behind their source database?

Open recipe
Database reliabilityAdvanced

Measure Database Replica Staleness by Region

Which replica regions are serving stale or failed reads?

Open recipe
Database reliabilityBeginner

Track Database Migration Failures by Release

Which releases contain failed or rolled-back database migrations?

Open recipe
Complete collectionsDatabase reliability SQL

Browse by implementation family

Compare related integration patterns

Templates to pair with this integration

More integrations