pg_stat_insightsAPI Reference

Complete API documentation for deep PostgreSQL performance analytics. All endpoints, parameters, responses, and code examples for database optimization.

20+ endpoints
PostgreSQL native
Real-time data

Base URL

http://localhost:8000/api/v1/insights

All pg_stat_insights API endpoints are prefixed with this base URL

API Endpoints

Complete reference for all analytics endpoints

Dashboard & Overview

Complete dashboard data and system overview

GET/dashboard

Get complete insights dashboard with all key metrics

Response

{
  "query_stats": {
    "total_queries": 1250,
    "slow_queries": 23,
    "avg_execution_time": 12.5,
    "total_execution_time": 15625
  },
  "table_stats": {
    "total_tables": 45,
    "bloated_tables": 3,
    "total_size_mb": 1024.5,
    "avg_bloat_percentage": 5.2
  },
  "cache_stats": {
    "buffer_hit_ratio": 98.5,
    "index_hit_ratio": 99.2,
    "toast_hit_ratio": 97.8
  },
  "connection_stats": {
    "active_connections": 15,
    "idle_connections": 8,
    "idle_in_transaction": 2
  },
  "replication_stats": {
    "lag_seconds": 0.5,
    "replication_slots": 2,
    "standby_servers": 2
  }
}
GET/summary

Get high-level performance summary

Response

{
  "overall_health": "good",
  "performance_score": 85,
  "critical_issues": 0,
  "warnings": 2,
  "recommendations_count": 5
}

Query Analytics

Deep query performance analysis and optimization

GET/queries

Get detailed query performance insights

Parameters

NameTypeRequiredDescription
limitintegerNoNumber of queries to return (default: 20, max: 100)
order_bystringNoSort by: calls, total_time, avg_time, rows (default: total_time)
min_callsintegerNoMinimum number of calls to include
min_avg_timefloatNoMinimum average execution time (ms)

Response

{
  "queries": [
    {
      "query_id": 12345,
      "query": "SELECT * FROM users WHERE email = $1",
      "calls": 150,
      "total_time": 1250.5,
      "avg_time": 8.34,
      "min_time": 2.1,
      "max_time": 45.2,
      "rows": 1,
      "shared_blks_hit": 1200,
      "shared_blks_read": 50,
      "local_blks_hit": 0,
      "local_blks_read": 0
    }
  ],
  "total_queries": 1250,
  "slowest_query_time": 245.8,
  "most_frequent_calls": 500
}
GET/queries/slow

Get slowest queries requiring optimization

Parameters

NameTypeRequiredDescription
thresholdfloatNoMinimum execution time threshold in ms (default: 100)
limitintegerNoNumber of queries to return (default: 10)

Response

{
  "slow_queries": [
    {
      "query": "SELECT u.*, p.* FROM users u JOIN profiles p ON u.id = p.user_id WHERE u.created_at > $1",
      "avg_time": 245.8,
      "calls": 25,
      "total_time": 6145,
      "optimization_potential": "high"
    }
  ]
}
GET/queries/frequent

Get most frequently executed queries

Parameters

NameTypeRequiredDescription
limitintegerNoNumber of queries to return (default: 10)
min_callsintegerNoMinimum number of calls (default: 10)

Response

{
  "frequent_queries": [
    {
      "query": "SELECT id, email FROM users WHERE id = $1",
      "calls": 500,
      "avg_time": 2.1,
      "total_time": 1050,
      "percentage_of_total": 40
    }
  ]
}

Table & Index Analysis

Table health, bloat analysis, and index optimization

GET/tables

Get comprehensive table statistics and bloat analysis

Parameters

NameTypeRequiredDescription
schemastringNoFilter by schema name
min_size_mbfloatNoMinimum table size in MB
bloat_thresholdfloatNoMinimum bloat percentage to include (default: 5.0)

Response

{
  "tables": [
    {
      "schema_name": "public",
      "table_name": "users",
      "size_mb": 45.2,
      "row_count": 10000,
      "bloat_percentage": 5.2,
      "bloat_size_mb": 2.3,
      "last_vacuum": "2024-01-15T08:00:00Z",
      "last_analyze": "2024-01-15T08:00:00Z",
      "vacuum_count": 15,
      "analyze_count": 12,
      "needs_vacuum": true,
      "needs_analyze": false
    }
  ],
  "total_tables": 45,
  "total_size_mb": 1024.5,
  "bloated_tables": 3,
  "avg_bloat_percentage": 5.2
}
GET/indexes

Get index usage statistics and optimization recommendations

Parameters

NameTypeRequiredDescription
schemastringNoFilter by schema name
unused_onlybooleanNoShow only unused indexes (default: false)
min_size_mbfloatNoMinimum index size in MB

Response

{
  "indexes": [
    {
      "schema_name": "public",
      "table_name": "users",
      "index_name": "idx_users_email",
      "size_mb": 2.1,
      "usage_count": 1250,
      "is_used": true,
      "usage_percentage": 95.2,
      "last_used": "2024-01-15T10:30:00Z",
      "index_type": "btree",
      "is_unique": true
    }
  ],
  "total_indexes": 78,
  "unused_indexes": 5,
  "total_index_size_mb": 156.8
}
GET/indexes/missing

Get missing index recommendations based on query patterns

Parameters

NameTypeRequiredDescription
min_benefitfloatNoMinimum benefit score (0-100)
limitintegerNoNumber of recommendations (default: 10)

Response

{
  "missing_indexes": [
    {
      "table_name": "orders",
      "column_name": "created_at",
      "benefit_score": 85.5,
      "estimated_improvement": "80% faster queries",
      "query_example": "SELECT * FROM orders WHERE created_at > $1",
      "frequency": 150
    }
  ]
}

Cache & Memory

Buffer cache analysis and memory optimization

GET/cache

Get comprehensive cache hit ratio statistics

Response

{
  "buffer_hit_ratio": 98.5,
  "index_hit_ratio": 99.2,
  "toast_hit_ratio": 97.8,
  "tup_hit_ratio": 99.1,
  "buffer_cache_size_mb": 1024,
  "shared_buffers_mb": 1024,
  "effective_cache_size_mb": 4096,
  "recommendations": [
    {
      "type": "increase_shared_buffers",
      "priority": "medium",
      "description": "Consider increasing shared_buffers to 25% of RAM"
    }
  ]
}
GET/cache/top_tables

Get tables with highest cache usage

Parameters

NameTypeRequiredDescription
limitintegerNoNumber of tables to return (default: 10)

Response

{
  "top_tables": [
    {
      "table_name": "users",
      "cache_hit_ratio": 99.5,
      "cache_size_mb": 45.2,
      "total_reads": 15000,
      "cache_hits": 14925,
      "cache_misses": 75
    }
  ]
}

Replication & Locks

Replication monitoring and lock analysis

GET/replication

Get replication lag and status information

Response

{
  "lag_seconds": 0.5,
  "replication_slots": [
    {
      "slot_name": "replica1",
      "active": true,
      "lag_bytes": 1024,
      "lag_wal": 0
    }
  ],
  "standby_servers": 2,
  "max_lag_seconds": 2.1,
  "avg_lag_seconds": 0.8
}
GET/locks

Get current lock information and blocking queries

Parameters

NameTypeRequiredDescription
blocking_onlybooleanNoShow only blocking locks (default: false)

Response

{
  "locks": [
    {
      "lock_type": "ExclusiveLock",
      "relation_name": "users",
      "mode": "ExclusiveLock",
      "granted": true,
      "pid": 12345,
      "query": "UPDATE users SET last_login = NOW() WHERE id = $1",
      "duration_seconds": 5.2
    }
  ],
  "blocking_locks": 0,
  "total_locks": 15,
  "longest_lock_duration": 5.2
}

Recommendations

Intelligent optimization recommendations

GET/recommendations

Get intelligent performance optimization recommendations

Parameters

NameTypeRequiredDescription
prioritystringNoFilter by priority: high, medium, low
categorystringNoFilter by category: query, index, cache, vacuum
limitintegerNoNumber of recommendations (default: 20)

Response

{
  "recommendations": [
    {
      "id": "rec_001",
      "type": "missing_index",
      "priority": "high",
      "category": "index",
      "title": "Add index on users.email",
      "description": "Query performance can be improved by 80% with an index on users.email",
      "impact": "high",
      "effort": "low",
      "sql_command": "CREATE INDEX idx_users_email ON users(email);",
      "affected_queries": 5,
      "estimated_improvement": "80% faster queries"
    }
  ],
  "total_recommendations": 8,
  "high_priority": 2,
  "medium_priority": 4,
  "low_priority": 2
}
GET/recommendations/vacuum

Get vacuum and analyze recommendations

Response

{
  "vacuum_recommendations": [
    {
      "table_name": "orders",
      "schema_name": "public",
      "bloat_percentage": 15.2,
      "last_vacuum": "2024-01-10T08:00:00Z",
      "vacuum_command": "VACUUM ANALYZE orders;",
      "priority": "high"
    }
  ]
}

Code Examples

Ready-to-use client implementations

Python Client

import asyncio
import aiohttp
from datetime import datetime, timedelta

class PgStatInsightsClient:
    def __init__(self, base_url="http://localhost:8000/api/v1/insights"):
        self.base_url = base_url
        self.session = None
    
    async def __aenter__(self):
        self.session = aiohttp.ClientSession()
        return self
    
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        if self.session:
            await self.session.close()
    
    async def get_dashboard(self):
        """Get complete insights dashboard"""
        async with self.session.get(f"{self.base_url}/dashboard") as response:
            return await response.json()
    
    async def get_slow_queries(self, threshold=100):
        """Get slowest queries"""
        params = {'threshold': threshold}
        async with self.session.get(f"{self.base_url}/queries/slow", params=params) as response:
            return await response.json()
    
    async def get_table_bloat(self, min_bloat=5.0):
        """Get tables with significant bloat"""
        params = {'bloat_threshold': min_bloat}
        async with self.session.get(f"{self.base_url}/tables", params=params) as response:
            return await response.json()
    
    async def get_recommendations(self, priority='high'):
        """Get optimization recommendations"""
        params = {'priority': priority}
        async with self.session.get(f"{self.base_url}/recommendations", params=params) as response:
            return await response.json()

# Usage
async def main():
    async with PgStatInsightsClient() as client:
        # Get dashboard overview
        dashboard = await client.get_dashboard()
        print(f"Total queries: {dashboard['query_stats']['total_queries']}")
        print(f"Cache hit ratio: {dashboard['cache_stats']['buffer_hit_ratio']}%")
        
        # Get slow queries
        slow_queries = await client.get_slow_queries(threshold=50)
        for query in slow_queries['slow_queries']:
            print(f"Slow query: {query['query'][:100]}...")
            print(f"Avg time: {query['avg_time']}ms")
        
        # Get recommendations
        recommendations = await client.get_recommendations('high')
        for rec in recommendations['recommendations']:
            print(f"Recommendation: {rec['title']}")
            print(f"Impact: {rec['impact']}, Effort: {rec['effort']}")

# Run the client
asyncio.run(main())

JavaScript/Node.js Client

class PgStatInsightsClient {
    constructor(baseUrl = 'http://localhost:8000/api/v1/insights') {
        this.baseUrl = baseUrl;
    }
    
    async request(endpoint, params = {}) {
        const url = new URL(`${this.baseUrl}${endpoint}`);
        Object.keys(params).forEach(key => 
            url.searchParams.append(key, params[key])
        );
        
        const response = await fetch(url);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return response.json();
    }
    
    async getDashboard() {
        return this.request('/dashboard');
    }
    
    async getSlowQueries(threshold = 100) {
        return this.request('/queries/slow', { threshold });
    }
    
    async getTableBloat(minBloat = 5.0) {
        return this.request('/tables', { bloat_threshold: minBloat });
    }
    
    async getRecommendations(priority = 'high') {
        return this.request('/recommendations', { priority });
    }
    
    async getCacheStats() {
        return this.request('/cache');
    }
    
    async getReplicationStatus() {
        return this.request('/replication');
    }
}

// Usage
const client = new PgStatInsightsClient();

async function analyzePerformance() {
    try {
        // Get overall dashboard
        const dashboard = await client.getDashboard();
        console.log('Performance Overview:');
        console.log(`Total queries: ${dashboard.query_stats.total_queries}`);
        console.log(`Cache hit ratio: ${dashboard.cache_stats.buffer_hit_ratio}%`);
        
        // Analyze slow queries
        const slowQueries = await client.getSlowQueries(50);
        console.log('\nSlow Queries:');
        slowQueries.slow_queries.forEach(query => {
            console.log(`- ${query.query.substring(0, 100)}...`);
            console.log(`  Avg time: ${query.avg_time}ms`);
        });
        
        // Check table bloat
        const tableBloat = await client.getTableBloat(10);
        console.log('\nTables with Bloat:');
        tableBloat.tables.forEach(table => {
            console.log(`- ${table.table_name}: ${table.bloat_percentage}% bloat`);
        });
        
        // Get recommendations
        const recommendations = await client.getRecommendations('high');
        console.log('\nHigh Priority Recommendations:');
        recommendations.recommendations.forEach(rec => {
            console.log(`- ${rec.title}`);
            console.log(`  Impact: ${rec.impact}, Effort: ${rec.effort}`);
        });
        
    } catch (error) {
        console.error('Error analyzing performance:', error);
    }
}

analyzePerformance();

cURL Examples

# Get complete dashboard
curl -X GET "http://localhost:8000/api/v1/insights/dashboard" \
  -H "Content-Type: application/json"

# Get slow queries (threshold 100ms)
curl -X GET "http://localhost:8000/api/v1/insights/queries/slow?threshold=100" \
  -H "Content-Type: application/json"

# Get frequent queries
curl -X GET "http://localhost:8000/api/v1/insights/queries/frequent?limit=5" \
  -H "Content-Type: application/json"

# Get table bloat analysis
curl -X GET "http://localhost:8000/api/v1/insights/tables?bloat_threshold=5.0" \
  -H "Content-Type: application/json"

# Get index usage statistics
curl -X GET "http://localhost:8000/api/v1/insights/indexes?unused_only=true" \
  -H "Content-Type: application/json"

# Get missing index recommendations
curl -X GET "http://localhost:8000/api/v1/insights/indexes/missing?min_benefit=50" \
  -H "Content-Type: application/json"

# Get cache statistics
curl -X GET "http://localhost:8000/api/v1/insights/cache" \
  -H "Content-Type: application/json"

# Get replication status
curl -X GET "http://localhost:8000/api/v1/insights/replication" \
  -H "Content-Type: application/json"

# Get current locks
curl -X GET "http://localhost:8000/api/v1/insights/locks?blocking_only=true" \
  -H "Content-Type: application/json"

# Get optimization recommendations
curl -X GET "http://localhost:8000/api/v1/insights/recommendations?priority=high&limit=10" \
  -H "Content-Type: application/json"

# Get vacuum recommendations
curl -X GET "http://localhost:8000/api/v1/insights/recommendations/vacuum" \
  -H "Content-Type: application/json"

HTTP Status Codes

Common error responses and their meanings

400

Bad Request

Invalid request parameters or malformed JSON

401

Unauthorized

Authentication required or invalid credentials

403

Forbidden

Insufficient permissions to access PostgreSQL system catalogs

404

Not Found

Requested resource or endpoint does not exist

422

Unprocessable Entity

Request validation failed or invalid parameter values

429

Too Many Requests

Rate limit exceeded for API requests

500

Internal Server Error

Unexpected server error or database connection issue

503

Service Unavailable

PostgreSQL service unavailable or extensions not installed

Performance Tips

Best practices for optimal API performance

Query Optimization

  • Use pagination with limit parameter
  • Filter results with min_calls, min_avg_time
  • Cache dashboard data for 30-60 seconds
  • Use specific endpoints instead of dashboard

Database Setup

  • Ensure pg_stat_statements is enabled
  • Grant pg_monitor role to API user
  • Set appropriate pg_stat_statements.max
  • Monitor query performance regularly

Interactive API Explorer

Try the API directly in your browser

Swagger UI Documentation

Interactive API documentation with live testing capabilities for all pg_stat_insights endpoints

Open API Explorer