This document describes how database query performance is monitored, optimized, and reviewed.
Performance indexes are managed through migrations (see 1738100000000_add-performance-indexes.js).
High-impact indexes include:
transactions(successful, created_at DESC)for filtered transaction feedstransactions(source_account, created_at DESC)for account activity and distinct countsoperations(type, created_at DESC)and partial payment index for analyticsaccount_metrics(account_id, timestamp DESC)for account dashboardsasset_metrics(asset_id, timestamp DESC)for latest asset metrics lookups
Apply migrations before relying on these indexes:
pnpm db:migrateThe API records every query duration and flags slow queries.
Environment variables:
SLOW_QUERY_THRESHOLD_MS(default:100)SLOW_QUERY_LOG_SIZE(default:50)STATS_CACHE_TTL_SECONDS(default:60)NETWORK_METRICS_CACHE_TTL_SECONDS(default:30)
Endpoints:
GET /metrics— Prometheus-style DB query countersGET /metrics/queries— JSON snapshot with recent slow queries
Slow queries are also written to API logs (warn level).
GraphQL resolvers use per-request DataLoaders (createLoaders()), including:
transactionLoadertransactionOperationsLoaderledgerLoader
Loaders batch lookups by key and deduplicate requests within a single GraphQL operation.
Redis cache-aside is used for expensive read paths:
statsquery (60s default TTL)networkMetricsquery (30s default TTL)
Cache keys are derived from query parameters to avoid stale cross-filter responses.
Run plan analysis against your database:
export DATABASE_URL=postgresql://stellar:stellar@localhost:5432/stellar_analytics
sh scripts/database/analyze-query-plans.shLook for:
Seq Scanon large tables where index scans are expected- High
actual time=inEXPLAIN ANALYZE - Large
rows removed by filter
Recommended monthly checklist:
- Review
/metrics/queriesslow-query log in staging/production - Run
scripts/database/analyze-query-plans.sh - Validate migration history (
pnpm db:migrate) - Capture top GraphQL operations and confirm DataLoader usage
- Record findings and open follow-up migrations for missing indexes
Migration workflow (.github/workflows/database-migrations.yml) ensures schema/index changes apply cleanly on fresh Postgres instances.