ankane/pghero · error · PgHero::NotEnabled

Query stats not enabled

Error message

Query stats not enabled

What it means

current_query_stats (the backing for query_stats and the /pghero/queries page) reads pg_stat_statements, which requires the extension to be installed in the database. query_stats_enabled? checks for it; when missing, PgHero raises NotEnabled "Query stats not enabled" before running any stats SQL.

Source

Thrown at lib/pghero/methods/query_stats.rb:207

              captured_at: captured_at,
              total_time: r[:total_time],
              calls: r[:calls],
              origin: r[:origin]
            }
          end
        end
        stats.each do |query|
          query[:average_time] = query[:total_time] / query[:calls]
        end
        stats
      end

      private

      # https://www.craigkerstiens.com/2013/01/10/more-on-postgres-performance/
      def current_query_stats(limit: nil, sort: nil, user: nil, query_hash: nil, origin: false)
        if !query_stats_enabled?
          raise NotEnabled, "Query stats not enabled"
        end

        limit ||= 100
        sort ||= "total_time"
        query = <<~SQL
          WITH query_stats AS (
            SELECT
              LEFT(query, 10000) AS query,
              queryid AS query_hash,
              rolname AS user,
              total_plan_time + total_exec_time AS total_time,
              #{"(total_plan_time + total_exec_time) / calls AS average_time," if sort == "average_time"}
              calls
            FROM
              pg_stat_statements
            INNER JOIN
              pg_database ON pg_database.oid = pg_stat_statements.dbid
            INNER JOIN

View on GitHub (pinned to 7edb57986f)

Solutions

  1. Enable it through pghero: PgHero.databases["primary"].enable_query_stats (runs CREATE EXTENSION IF NOT EXISTS pg_stat_statements)
  2. If CREATE fails, add pg_stat_statements to shared_preload_libraries in postgresql.conf (or the managed-service parameter group), restart Postgres, then retry
  3. Check availability first: SELECT * FROM pg_available_extensions WHERE name = 'pg_stat_statements'

Example fix

# before - raises NotEnabled until the extension exists
database.query_stats

# after - ensure extension first, then query
database.enable_query_stats
database.query_stats
Defensive patterns

Strategy: validation

Validate before calling

unless database.query_stats_enabled?
  database.enable_query_stats # requires pg_stat_statements in shared_preload_libraries
end
database.query_stats

Try / catch

begin
  database.query_stats
rescue PgHero::NotEnabled => e
  # enable once (or surface setup instructions), then retry manually - do not loop
  Rails.logger.warn("#{e.message} - run database.enable_query_stats")
end

Prevention

When it happens

Trigger: Visiting the pghero Queries tab or calling database.query_stats on a database where CREATE EXTENSION pg_stat_statements was never run; the extension was dropped (e.g. someone ran database.disable_query_stats); the server lacks pg_stat_statements in shared_preload_libraries so it cannot even be created.

Common situations: New or newly-attached databases in a multi-database pghero setup; managed Postgres where the extension is available but not preloaded (requires a parameter-group change and restart); testing against a fresh local Postgres container.

Related errors


AI-assisted analysis of ankane/pghero@7edb57986f (2026-08-21). Data as JSON: /api/errors/f408cf715dbfb619. Report an issue: GitHub.