# Slow query logging or monitoring is configured

- **Pattern:** `ab-000923` (`database-design-operations.monitoring-ops.slow-query-monitoring`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000923
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000923)

## Why it matters

Without slow query logging, a query that degrades from 50ms to 5000ms as the database grows is invisible until users file support tickets or error rates spike. By then, the query has been running slowly for hours or days. ISO 25010 time-behaviour requires that performance characteristics are observable and measurable; a database layer with no query timing instrumentation provides no signal for performance regressions introduced by new code, schema changes, or data volume growth.

## Severity rationale

Low because slow query visibility affects detection speed rather than causing direct failures — performance degradation goes unnoticed longer, but the system continues to function.

## Remediation

Configure Prisma event listeners or a `pg` query wrapper to log queries over 1 second. For production, send slow query events to your existing observability platform.

```ts
// lib/prisma.ts — log slow queries
const prisma = new PrismaClient({
  log: [{ level: 'query', emit: 'event' }]
})
prisma.$on('query', (e) => {
  if (e.duration > 1000) {
    console.warn(`[slow-query] ${e.duration}ms: ${e.query}`)
    // Sentry.captureMessage(`Slow query: ${e.duration}ms`, 'warning')
  }
})
```

```ts
// Custom pg Pool timing wrapper
const origQuery = pool.query.bind(pool)
pool.query = async (...args: Parameters<typeof origQuery>) => {
  const t = Date.now()
  const result = await origQuery(...args)
  const ms = Date.now() - t
  if (ms > 1000) console.warn(`[slow-query] ${ms}ms`, args[0])
  return result
}
```

For Postgres server-level logging (self-hosted): add `log_min_duration_statement = 1000` to `postgresql.conf`.

## Detection

- **ID:** `slow-query-monitoring`
- **Severity:** `low`
- **What to look for:** List all query logging configurations and check for query performance monitoring configuration. In Prisma: look for `log: ['query', 'warn', 'error']` option in `new PrismaClient()`, or event listeners via `prisma.$on('query', ...)`. In raw `pg` Pool: look for `pg` event listeners or a query wrapper that measures elapsed time. In Postgres server config: look for `log_min_duration_statement` in `postgresql.conf` or Supabase database settings. In APM tools: check for Sentry performance integration, Datadog APM, New Relic, or similar that captures database query spans. Check deployment config or README for any mention of database performance monitoring. Also look for custom query middleware that wraps database calls to measure execution time.
- **Pass criteria:** Slow queries are logged or monitored — at least 1 monitoring mechanism configured. Either: Prisma logging is configured with a threshold, Postgres `log_min_duration_statement` is set, an APM tool captures database performance, or a custom timing wrapper is in place. There is a mechanism to detect and alert on slow queries before they affect users.
- **Fail criteria:** No query logging or performance monitoring of any kind. Slow queries would only be discovered after users complain about performance. No timing instrumentation around database calls.
- **Skip (N/A) when:** Application uses no database, or uses only a read-only data source with no performance-critical queries.
- **Detail on fail:** Example: `"No query logging configured in PrismaClient or pg Pool. No APM integration found. Slow database queries would be invisible until causing user-visible latency."`.
- **Remediation:** Configure slow query logging:

  ```ts
  // Prisma — enable query logging with performance events
  const prisma = new PrismaClient({
    log: [
      { level: 'query', emit: 'event' },
      { level: 'warn', emit: 'stdout' },
      { level: 'error', emit: 'stdout' },
    ],
  })

  // Log slow queries (over 1 second)
  prisma.$on('query', (e) => {
    if (e.duration > 1000) {
      console.warn(`Slow query (${e.duration}ms): ${e.query}`)
      // Send to monitoring: Sentry.captureMessage(`Slow query: ${e.duration}ms`)
    }
  })
  ```

  ```ts
  // Custom timing wrapper for pg Pool
  const originalQuery = pool.query.bind(pool)
  pool.query = async function(...args: Parameters<typeof originalQuery>) {
    const start = Date.now()
    const result = await originalQuery(...args)
    const duration = Date.now() - start
    if (duration > 1000) {
      console.warn(`Slow DB query (${duration}ms):`, args[0])
    }
    return result
  }
  ```

  ```sql
  -- Postgres server config — log queries slower than 1 second
  -- For Supabase: contact support or use their dashboard query analyzer
  -- For self-hosted: add to postgresql.conf
  log_min_duration_statement = 1000  -- milliseconds
  ```

---

## External references

- iso-25010 performance-efficiency.time-behaviour

Taxons: observability, performance

HTML version: https://auditbuffet.com/patterns/ab-000923
