neondatabase/neon · error

could not get database statistics: {}

Error message

could not get database statistics: {}

What it means

Thrown by the compute_ctl activity monitor thread (ComputeMonitor::check) when get_database_stats() fails. That helper runs one SELECT over pg_catalog.pg_stat_database summing active_time and sessions for all non-system databases, so this error means tokio_postgres could not execute the query or fetch the row. The monitor treats any such failure as suspicious (broken connection, statement timeout, invalid data), reports Postgres downtime via the PG_CURR_DOWNTIME_MS/PG_TOTAL_DOWNTIME_MS metrics, reconnects, and retries on the next 500ms tick. It only executes when the ActivityMonitorExperimental feature flag is enabled.

Source

Thrown at compute_tools/src/monitor.rs:239

                    }
                    self.active_time = Some(active_time);

                    if let Some(prev_sessions) = self.sessions {
                        if sessions != prev_sessions {
                            detected_activity = true;
                        }
                    }
                    self.sessions = Some(sessions);

                    if detected_activity {
                        // Update the last active time and continue, we don't need to
                        // check backends state change.
                        self.last_active = Some(Utc::now());
                        return Ok(());
                    }
                }
                Err(e) => {
                    return Err(anyhow::anyhow!("could not get database statistics: {}", e));
                }
            }
        }

        // If database statistics are the same, check all backends for state changes.
        // Maybe there are some with more recent activity. `get_backends_state_change()`
        // can return None or stale timestamp, so it's `compute.update_last_active()`
        // responsibility to check if the new timestamp is more recent than the current one.
        // This helps us to discover new sessions that have not done anything yet.
        match get_backends_state_change(cli) {
            Ok(last_active) => match (last_active, self.last_active) {
                (Some(last_active), Some(prev_last_active)) => {
                    if last_active > prev_last_active {
                        self.last_active = Some(last_active);
                        return Ok(());
                    }
                }
                (Some(last_active), None) => {

View on GitHub (pinned to 8f60b04da4)

Solutions

  1. Read the nested error text after the colon - it carries the underlying tokio_postgres error and SQLSTATE (connection closed, statement timeout, etc.) which identifies the real cause
  2. Check that Postgres is accepting connections on the monitor's connstr and that the compute reached the Running state (wait_for_postgres_start already gates this)
  3. Tolerate isolated occurrences: the monitor automatically reconnects (client = conf.connect(NoTls)) on the next iteration, so single failures during suspend/resume are expected; only chase repeated ones
  4. If it repeats with timeouts, raise statement_timeout for the cloud_admin monitor role or reduce load
Defensive patterns

Strategy: retry

Try / catch

// in the polling loop: log, count downtime, reconnect, continue
match monitor.check(cli) {
    Ok(_) => monitor.report_up(),
    Err(e) => {
        error!("could not check Postgres: {e}");
        monitor.report_down();
        client = conf.connect(NoTls); // fresh connection for the next tick
    }
}

Prevention

When it happens

Trigger: cli.query_one() on pg_stat_database returns Err: the TCP connection silently died (the code comments note queries fail with 'connection closed' while Client::is_closed() still returns false), a statement_timeout aborted the SELECT, or Postgres restarted/crashed mid-query.

Common situations: Autoscaled Neon computes being suspended or restarted while the monitor polls every 500ms; heavy user load causing timeouts on catalog statistics views; local dev against a Postgres that was killed without closing its sockets.

Related errors


AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16). Data as JSON: /api/errors/c0c8b30a50a6c77d. Report an issue: GitHub.