Skip to content

PgHero Integration

Date: November 26, 2025
Category: Features / Database
Status: Active

PgHero is integrated as a PostgreSQL performance dashboard, accessible via the CRM at /pghero.

Since the app uses webpack (not Sprockets), PgHero’s assets are copied to the public/ folder for static serving. A Rack::Rewrite rule strips locale prefixes from asset paths.

config/initializers/pghero.rb
PgHero.config_path = Rails.root.join('config', 'pghero.yml')
config/pghero.yml
development:
query_stats:
enabled: true
slow_query_ms: 50
index_suggestions:
enabled: true
explain:
enabled: true
analyze: true # Safe in development
production:
query_stats:
enabled: true
explain:
enabled: false # Never EXPLAIN ANALYZE in production
config/routes/crm.rb
mount PgHero::Engine, at: '/pghero' if defined?(PgHero)
# config/routes.rb - Exclude from locale filter
filter :locale, exclude: %r{/(?:...|pghero|...)/}
  1. Log in to CRM as admin
  2. Navigate to https://crm.warmlyyours.me:3000/pghero
  3. Dashboard shows database health overview
FeatureDescription
OverviewHealth checks summary (connections, vacuum, slow queries)
QueriesSlow query analysis from pg_stat_statements
SpaceTable sizes and bloat analysis
ConnectionsActive database connections
Live QueriesCurrently running queries
MaintenanceVacuum and analyze status
ExplainQuery plan analysis (EXPLAIN ANALYZE)
TunePostgreSQL configuration suggestions
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
CREATE EXTENSION IF NOT EXISTS hypopg; -- For index recommendations

These are created automatically by the Docker init script: docker/pg-init-scripts/05-pghero-extensions.sql

PgHero’s assets are committed to public/ for static serving. They only need to be regenerated when the PgHero gem version is updated:

Terminal window
./script/copy_pghero_assets.sh
git add public/stylesheets/pghero public/javascripts/pghero public/images/pghero
git commit -m "chore(pghero): update assets for pghero X.Y.Z"

Only run this when: PgHero gem version changes in Gemfile.lock

FilePurpose
config/initializers/pghero.rbPgHero configuration
config/pghero.ymlDatabase-specific settings
config/routes/crm.rbRoute mounting
config/routes.rbLocale exclusion for /pghero
config/initializers/260_redirections.rbRewrite rule for asset paths
script/copy_pghero_assets.shAsset extraction (run on gem update)
docker/pg-init-scripts/05-pghero-extensions.sqlPostgreSQL extensions
public/stylesheets/pghero/Static CSS (committed)
public/javascripts/pghero/Static JS (committed)
public/images/pghero/Static images (committed)

Ensure /pghero is in the locale exclusion pattern in config/routes.rb.

Verify pg_stat_statements extension is enabled:

SELECT * FROM pg_extension WHERE extname = 'pg_stat_statements';

Verify hypopg extension is enabled:

SELECT * FROM pg_extension WHERE extname = 'hypopg';

Enable pg_stat_statements on your production PostgreSQL server:

-- As superuser (postgres)
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- Add to postgresql.conf:
-- shared_preload_libraries = 'pg_stat_statements'
-- pg_stat_statements.track = all
-- Grant access to application user
GRANT pg_read_all_stats TO your_app_user;

⚠️ Important: Enabling pg_stat_statements requires a PostgreSQL restart.

PgHero assets are committed to the repository - no deployment step needed.

If you update the PgHero gem version, regenerate assets locally:

Terminal window
./script/copy_pghero_assets.sh
git add public/stylesheets/pghero public/javascripts/pghero public/images/pghero
git commit -m "chore(pghero): update assets for pghero X.Y.Z"

The config/pghero.yml is already configured for production:

production:
query_stats:
enabled: true
slow_query_ms: 50
index_suggestions:
enabled: true
explain:
enabled: false # Never EXPLAIN ANALYZE in production!

PgHero is protected by admin authentication:

  • Route: authenticate :account, ->(account) { account.is_admin? }
  • Only admins can access /pghero

For replica or read-only database analysis, add to config/pghero.yml:

production:
databases:
primary:
url: <%= ENV['DATABASE_URL'] %>
replica:
url: <%= ENV['DATABASE_REPLICA_URL'] %>
  • PgHero GitHub
  • Performance Profiling Stack
  • PostgreSQL Docker Image