Demo mode — This is sample data. Sign up free to monitor your own databases.
← Demo Dashboard

Production

72
Health score
Cache
95 99.2% buffer, 98.8% index
Indexes
60 6 unused (48.0 MB)
Bloat
55 12.5% bloat ratio
Queries
100 No long-running queries
Vacuum
68 7.2% dead tuples
Connections
100 18/100 (18.0%)

Health trend

0255075100Apr 30May 1May 1May 2May 2b7d9f12c4e8a56a3f8c2188 — Apr 30, 11:13am87 — Apr 30, 4:01pm85 — Apr 30, 8:49pm82 — May 1, 1:37am78 — May 1, 6:25am65 — May 1, 11:13am62 — May 1, 4:01pm60 — May 1, 8:49pm63 — May 2, 1:37am66 — May 2, 6:25am68 — May 2, 11:13am70 — May 2, 4:01pm71 — May 2, 8:49pm72 — May 3, 1:37am72 — May 3, 6:25am72 — May 3, 11:08am

Recommendations 3

Warning Indexes 6 unused indices wasting 48.0 MB

These indexes have had 0 scans since stats were last reset. Every write (INSERT/UPDATE/DELETE) still pays the cost of maintaining them. Stats have been accumulating for 21.0 days — reliable enough to act on, but always verify on production.

What to do
Generate ready-to-run DROP statements (review before executing):

SELECT
  'DROP INDEX CONCURRENTLY ' || indexrelname || ';' AS drop_statement,
  relname AS table,
  pg_size_pretty(pg_relation_size(indexrelid)) AS size
FROM pg_stat_user_indexes
JOIN pg_index USING (indexrelid)
WHERE idx_scan = 0
  AND NOT indisprimary
  AND NOT indisunique
ORDER BY pg_relation_size(indexrelid) DESC;

Only run on production after at least 2 weeks of stats accumulation.
Warning Bloat Moderate table bloat (12.5% dead tuple ratio)

Autovacuum may be falling behind on high-write tables.

What to do
Run VACUUM ANALYZE. If this persists, lower autovacuum_vacuum_scale_factor (default 0.2 = 20% dead tuples before trigger — try 0.05 for busy tables).
Warning Vacuum 2 tables flagged for vacuum

2 tables have a dead tuple ratio above 10% with live rows present.

What to do
Run: VACUUM ANALYZE;
To target specific tables:
SELECT relname, n_dead_tup, n_live_tup,
  round(n_dead_tup::numeric/nullif(n_live_tup+n_dead_tup,0)*100,1) AS dead_pct
FROM pg_stat_user_tables
WHERE n_dead_tup > n_live_tup * 0.1 AND n_live_tup > 0
ORDER BY dead_pct DESC;

N+1 queries 3

Queries executing more than twice per request on average.

Critical orders#index ~24.7 calls/request (max 50, sampled 312 requests)
Introduced in deploy c4e8a56 — Bump pg gem to 1.6.0 (1d ago)
Query pattern
SELECT "line_items".* FROM "line_items" WHERE "line_items"."order_id" = $1
Example SQL
SELECT "line_items".* FROM "line_items" WHERE "line_items"."order_id" = 4821
What to do
This query runs ~24.7x per request in orders#index.

This looks like an N+1 — loading line_items rows one at a time.
In your controller or model, add eager loading:

  # Before (N+1):
  @records = Parent.all
  # each record.line_item triggers a query

  # After (eager loaded):
  @records = Parent.includes(:line_item)
Critical orders#index ~24.7 calls/request (max 50, sampled 312 requests)
Introduced in deploy c4e8a56 — Bump pg gem to 1.6.0 (1d ago)
Query pattern
SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2
Example SQL
SELECT "users".* FROM "users" WHERE "users"."id" = 917 LIMIT 1
What to do
This query runs ~24.7x per request in orders#index.

This looks like an N+1 — loading users rows one at a time.
In your controller or model, add eager loading:

  # Before (N+1):
  @records = Parent.all
  # each record.user triggers a query

  # After (eager loaded):
  @records = Parent.includes(:user)
Warning products#show ~8.3 calls/request (max 22, sampled 189 requests)
Introduced in deploy b7d9f12 — Add eager loading to orders#index (2d ago)
Query pattern
SELECT "product_variants".* FROM "product_variants" WHERE "product_variants"."product_id" = $1
Example SQL
SELECT "product_variants".* FROM "product_variants" WHERE "product_variants"."product_id" = 156
What to do
This query runs ~8.3x per request in products#show.

This looks like an N+1 — loading product_variants rows one at a time.
In your controller or model, add eager loading:

  # Before (N+1):
  @records = Parent.all
  # each record.product_variant triggers a query

  # After (eager loaded):
  @records = Parent.includes(:product_variant)

Latest snapshot

Buffer hit ratio
99.20%
Index hit ratio
98.80%
Unused indexes
6 (48.0 MB)
Bloat ratio
12.5%
Long-running queries
0
Dead tuples
185,000
Connections
18 / 100
Snapshot taken
5m ago
Git commit
a3f8c21 — Fix order total calculation for discounts

Recent deploys

8h ago production
a3f8c21 Fix order total calculation for discounts
Eric M
1d ago production
c4e8a56 Bump pg gem to 1.6.0
Eric M
2d ago production
b7d9f12 Add eager loading to orders#index
Sarah Chen

Like what you see?

Start free — no credit card

Free tier: 1 database, 3-day history. Upgrade anytime.