ankane/pghero · warning · PgHero::NotEnabled
Historical query stats not enabled
Error message
Historical query stats not enabled
What it means
PgHero raises this from PgHero::Methods::QueryStats#historical_query_stats when historical_query_stats_enabled? is false. Historical (time-ranged) query stats are an opt-in layer on top of live pg_stat_statements: they require the pghero_queries and pghero_query_stats capture tables to exist AND capture_query_stats not set to false for the database in config/pghero.yml. Without both, PgHero has no stored snapshots to aggregate with SUM(total_time)/SUM(calls) and refuses rather than returning empty data.
Source
Thrown at lib/pghero/methods/query_stats.rb:265
SELECT NULL, #{"NULL, " if origin}NULL, NULL, SUM(total_time), NULL FROM query_stats
)
SQL
binds = {limit: limit.to_i}
binds[:user] = user if user
binds[:query_hash] = query_hash if query_hash
# we may be able to skip query_columns
# in more recent versions of Postgres
# as pg_stat_statements should be already normalized
result = select_all(query, binds, query_columns: [:query])
total = result.pop
[result, total[:total_time] || 0]
end
def historical_query_stats(limit: nil, sort: nil, user: nil, query_hash: nil, start_at: nil, end_at: nil)
if !historical_query_stats_enabled?
raise NotEnabled, "Historical query stats not enabled"
end
limit ||= 100
sort ||= "total_time"
query = <<~SQL
WITH query_stats AS (
SELECT
query_hash,
"user",
query_id,
SUM(total_time) AS total_time,
SUM(calls) AS calls
FROM
pghero_query_stats
WHERE
database = :id
#{"AND captured_at >= :start_at" if start_at}
#{"AND captured_at <= :end_at" if end_at}View on GitHub (pinned to 7edb57986f)
Solutions
- Run `rails generate pghero:query_stats` followed by `rails db:migrate` to create pghero_queries and pghero_query_stats.
- Ensure config/pghero.yml does not set capture_query_stats: false for the database in question (removing the key defaults to enabled).
- Schedule `rake pghero:capture_query_stats` at least hourly (cron, whenever, sidekiq-cron) so snapshots accumulate before you query history.
- If the feature is intentionally off, guard callers with `PgHero.historical_query_stats_enabled?` or rescue PgHero::NotEnabled and fall back to `PgHero.query_stats` (live pg_stat_statements data).
Example fix
# before - raises PgHero::NotEnabled: Historical query stats not enabled PgHero.historical_query_stats(start_at: 7.days.ago, end_at: 1.hour.ago) # after # terminal: # rails generate pghero:query_stats # rails db:migrate # config/schedule.rb: # every :hour do # rake "pghero:capture_query_stats" # end stats = PgHero.historical_query_stats(start_at: 7.days.ago, end_at: 1.hour.ago) if PgHero.historical_query_stats_enabled?
Defensive patterns
Strategy: validation
Validate before calling
return unless PgHero.historical_query_stats_enabled? stats = PgHero.historical_query_stats(start_at: 7.days.ago, end_at: 1.hour.ago)
Type guard
# Ruby predicate - the closest thing to a type guard def historical_stats_available? PgHero.historical_query_stats_enabled? end
Try / catch
begin
PgHero.historical_query_stats(start_at: 24.hours.ago)
rescue PgHero::NotEnabled
Rails.logger.info("PgHero historical query stats not configured; using live stats")
PgHero.query_stats
end Prevention
- Run the pghero:query_stats generator and migration as part of setup, not later.
- Schedule `rake pghero:capture_query_stats` hourly via cron/whenever from day one.
- Check historical_query_stats_enabled? in a boot health check for environments where history matters.
- Keep capture_query_stats unset (defaults on) unless you intentionally disable it per database.
When it happens
Trigger: Calling PgHero.historical_query_stats(start_at: ..., end_at: ...) (or the web UI queries page with a historical time range) before `rails generate pghero:query_stats && rails db:migrate` has created the capture tables; or when config/pghero.yml sets capture_query_stats: false for that database; or on an environment where the migration ran but the config disables capture.
Common situations: Fresh PgHero install where the optional migration was skipped; migration applied in development but not in staging/production; the hourly `rake pghero:capture_query_stats` cron was never scheduled so nobody noticed the feature was inactive; pghero.yml copied from another environment with capture_query_stats: false.
Related errors
- Space stats not enabled
- Suggested indexes not enabled
- System stats not enabled
- Query hash stats not enabled
- Query stats not enabled
AI-assisted analysis of ankane/pghero@7edb57986f (2026-08-21).
Data as JSON: /api/errors/c3b79743f0cda15a.
Report an issue: GitHub.