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
- 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
- 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)
- 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
- 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
- Keep the monitor's connstr stable and only start monitoring once the compute is in Running state
- Alert on consecutive monitor errors, not single occurrences - the loop self-heals every 500ms
- Avoid statement_timeout values aggressive enough to kill catalog-statistics queries
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
- could not query active_time: {}
- could not get backends state change: {}
- could not query backends: {}
- connection to postgres closed
- failed to get list of active logical replication subscriptio
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/c0c8b30a50a6c77d.
Report an issue: GitHub.