pg_stat_insightsAPI Reference
Complete API documentation for deep PostgreSQL performance analytics. All endpoints, parameters, responses, and code examples for database optimization.
Base URL
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
/dashboardGet 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
}
}/summaryGet 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
/queriesGet detailed query performance insights
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Number of queries to return (default: 20, max: 100) |
| order_by | string | No | Sort by: calls, total_time, avg_time, rows (default: total_time) |
| min_calls | integer | No | Minimum number of calls to include |
| min_avg_time | float | No | Minimum 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
}/queries/slowGet slowest queries requiring optimization
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| threshold | float | No | Minimum execution time threshold in ms (default: 100) |
| limit | integer | No | Number 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"
}
]
}/queries/frequentGet most frequently executed queries
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Number of queries to return (default: 10) |
| min_calls | integer | No | Minimum 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
/tablesGet comprehensive table statistics and bloat analysis
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| schema | string | No | Filter by schema name |
| min_size_mb | float | No | Minimum table size in MB |
| bloat_threshold | float | No | Minimum 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
}/indexesGet index usage statistics and optimization recommendations
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| schema | string | No | Filter by schema name |
| unused_only | boolean | No | Show only unused indexes (default: false) |
| min_size_mb | float | No | Minimum 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
}/indexes/missingGet missing index recommendations based on query patterns
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| min_benefit | float | No | Minimum benefit score (0-100) |
| limit | integer | No | Number 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
/cacheGet 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"
}
]
}/cache/top_tablesGet tables with highest cache usage
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Number 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
/replicationGet 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
}/locksGet current lock information and blocking queries
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| blocking_only | boolean | No | Show 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
/recommendationsGet intelligent performance optimization recommendations
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| priority | string | No | Filter by priority: high, medium, low |
| category | string | No | Filter by category: query, index, cache, vacuum |
| limit | integer | No | Number 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
}/recommendations/vacuumGet 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
Bad Request
Invalid request parameters or malformed JSON
Unauthorized
Authentication required or invalid credentials
Forbidden
Insufficient permissions to access PostgreSQL system catalogs
Not Found
Requested resource or endpoint does not exist
Unprocessable Entity
Request validation failed or invalid parameter values
Too Many Requests
Rate limit exceeded for API requests
Internal Server Error
Unexpected server error or database connection issue
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