All skills
planetscale avatar

/postgres

@2b8cda6 official

PostgreSQL best practices, query optimization, connection troubleshooting, and performance improvement. Load when working with Postgres databases.

Use this Skill: https://skilld.dev/gh/planetscale/database-skills/postgres

This session only. Nothing lands on disk.

referencesindex-optimization.md

≈1.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Index Optimization

Identify Unused Indexes

Query to find unused indexes:

-- indexes with 0 scans (check pg_stat_reset / pg_postmaster_start_time first)
SELECT
   s.schemaname,
   s.relname AS table_name,
   s.indexrelname AS index_name,
   pg_size_pretty(pg_relation_size(s.indexrelid)) AS index_size
 FROM pg_catalog.pg_stat_user_indexes s
 JOIN pg_catalog.pg_index i ON s.indexrelid = i.indexrelid
 WHERE s.idx_scan = 0
   AND 0 <> ALL (i.indkey)       -- exclude expression indexes
   AND NOT i.indisunique          -- exclude UNIQUE indexes
   AND NOT EXISTS (               -- exclude constraint-backing indexes
     SELECT 1 FROM pg_catalog.pg_constraint c
     WHERE c.conindid = s.indexrelid
   )
 ORDER BY pg_relation_size(s.indexrelid) DESC;

Identify Duplicate Indexes

Indexes with identical definitions (after normalizing names) on the same table are duplicates:

SELECT
  schemaname || '.' || tablename AS table,
  array_agg(indexname) AS duplicate_indexes,
  pg_size_pretty(sum(pg_relation_size((schemaname || '.' || indexname)::regclass))) AS total_size
FROM pg_indexes
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
GROUP BY schemaname, tablename,
  regexp_replace(indexdef, 'INDEX \S+ ON ', 'INDEX ON ')
HAVING count(*) > 1;

Warning: Confirm with a human before dropping duplicate indexes. Some "duplicates" differ in practical use (operator classes, collations, predicates, sort order) and may be required for critical workloads.

Identify Invalid Indexes

Failed CREATE INDEX CONCURRENTLY builds leave INVALID indexes maintained on every write but never used for reads. CREATE INDEX CONCURRENTLY IF NOT EXISTS silently succeeds if an invalid index already exists — always check and drop before retrying.

SELECT indexrelname FROM pg_stat_user_indexes s
JOIN pg_index i ON s.indexrelid = i.indexrelid WHERE NOT i.indisvalid;

Warning: Confirm with a human before dropping invalid indexes. Validate index health and workload impact first, then drop/rebuild during a controlled window.

Per-table Index Count Guidelines

Index Count Recommendation
<5 Normal
5-10 Review for unused/duplicates
>10 Audit required - significant write overhead
SELECT relname AS table, count(*) as index_count
FROM pg_stat_user_indexes
GROUP BY relname
ORDER BY count(*) DESC;

Index Bloat Detection

VACUUM removes dead tuples but does not reclaim empty index page space — only REINDEX or pg_repack compacts pages. Detect with pgstattuple:

CREATE EXTENSION IF NOT EXISTS pgstattuple;
SELECT avg_leaf_density FROM pgstatindex('my_index');

Below 70% = significant bloat, healthy = 80-90%+. Remediation: REINDEX CONCURRENTLY (PG 12+) for index-only bloat; pg_repack for table+index (requires PK and ~2x disk space).

HOT Update Monitoring

HOT updates skip all index maintenance when no indexed column value changes and free space exists on the same heap page. Target >90% on frequently updated tables.

SELECT relname, round(100.0 * n_tup_hot_upd / nullif(n_tup_upd, 0), 1) AS hot_pct
FROM pg_stat_user_tables WHERE n_tup_upd > 0 ORDER BY n_tup_upd DESC;

Key levers: set fillfactor = 70-80 on write-heavy tables, never index frequently-updated columns (status, updated_at) unless query-critical, use partial indexes to reduce scope. PG 16+: BRIN indexes excluded from HOT eligibility checks.

Write Amplification

Each additional index adds write-path overhead because every INSERT/UPDATE/DELETE must maintain more index entries. In a Percona PG 17.4 over-indexing benchmark, moving from 7 to 39 indexes showed a 58% throughput drop.

To reduce WAL volume from this extra write activity, enable wal_compression (available before PG 15; lz4 and zstd options are PG 15+). Tune max_wal_size separately to reduce checkpoint frequency under sustained write load.

Planner Tuning

  • SSD storage: random_page_cost = 1.1 (default 4.0 assumes spinning disk)
  • effective_cache_size: ~75% of total RAM
  • Correlated columns: CREATE STATISTICS (dependencies, ndistinct, mcv) then ANALYZE
  • Skewed distributions: ALTER TABLE ... ALTER COLUMN ... SET STATISTICS 500-1000

Source: SKILL.md on GitHub

1 alert17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    The skill provides comprehensive documentation, best practices, and diagnostic SQL queries for PostgreSQL and PlanetScale-specific features. No security issues were identified.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer6mo

    18/23 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 2b8cda6. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Activeupdated 7 months ago
metadata
{
  "author": "planetscale",
  "version": "1.0.0"
}
  • Database
  • postgres
  • schema-design
  • indexing
  • query-optimization
  • replication
  • monitoring
  • backup-recovery
  • planetscale

README badge

README badge for planetscale/database-skills/postgres

Provides Postgres best practices, query optimization guidance, indexing strategies, and schema design patterns. Includes PlanetScale-specific connection pooling, monitoring, and CLI reference for hosted Postgres deployments.

Generated from the current SKILL.md.

Does this skill cover PlanetScale-specific features like connection pooling?
Yes. The skill includes references for PlanetScale connection pooling, PgBouncer configuration, the pscale CLI, and PlanetScale Insights for slow query analysis.
What topics does this skill cover?
Schema design, indexing, query optimization, partitioning, MVCC and transactions, replication, WAL operations, monitoring, backup/recovery, and PlanetScale-specific connection and deployment workflows.
Does this skill help with query performance troubleshooting?
Yes. It includes guidance on query patterns, index optimization, MVCC transaction isolation, and monitoring via pg_stat views and pg_stat_statements.
Can I use this skill if I self-host Postgres instead of PlanetScale?
Yes. The skill covers generic Postgres best practices and operations. PlanetScale-specific references are optional and only used if you choose PlanetScale for hosting.

Generated from the current SKILL.md. These answers refresh after source changes.