Lightweight PostgreSQL extension for query tracing and latency metrics.
Pgtrace hooks into the PostgreSQL executor to record aggregate query metrics in shared memory. It exposes views for total/failed/slow queries and a latency histogram. The design is intentionally minimal to keep overhead low.
- Per-query fingerprinting with detailed stats (calls, errors, latency, timestamps)
- Tracks total, failed, and slow queries (global metrics)
- Latency histogram across 6 buckets
- GUCs for enable/disable and slow-query threshold
- Shared-memory metrics (cross-backend)
- PostgreSQL 15+ (tested on PostgreSQL 16)
postgresql-server-dev-16(or matching server dev package)- Build tools (
make,gcc/clang)
make
sudo make installPgtrace uses shared memory, so it must be loaded via shared_preload_libraries.
echo "shared_preload_libraries = 'pgtrace'" | sudo tee -a /etc/postgresql/16/main/postgresql.conf
sudo systemctl restart postgresql@16-mainsudo -u postgres psql -c "CREATE EXTENSION pgtrace;"SELECT * FROM pgtrace_query_stats;Columns:
fingerprint(bigint) - 64-bit hash of normalized querycalls(bigint) - Number of executionserrors(bigint) - Number of failed executionstotal_time_ms(double precision) - Total execution timeavg_time_ms(double precision) - Average execution timemax_time_ms(double precision) - Maximum execution timefirst_seen(timestamptz) - First execution timestamplast_seen(timestamptz) - Last execution timestampis_new(boolean) - First execution (potential intrusion)is_anomalous(boolean) - Latency or scan anomaly detectedempty_app_count(bigint) - Times executed without application_namescan_ratio(double precision) - Rows scanned / rows returned (efficiency)total_rows_returned(bigint) - Cumulative rows returned
Proactive intelligence for suspicious queries:
SELECT * FROM pgtrace_alien_queries
WHERE is_new OR is_anomalous
ORDER BY avg_time_ms DESC;Identifies:
- New fingerprints: Never-before-seen queries (potential unauthorized access)
- Anomalous latency: Queries running 3× slower than baseline
- Inefficient scans: Rows scanned > 100× rows returned (full table scans)
- Missing app context: Queries with empty
application_name(suspicious)
This view combines all alien indicators in one place for rapid response.
Capture recent worst-performing queries for actionable optimization. Stores:
SELECT * FROM pgtrace_slow_queries
ORDER BY duration_ms DESC
LIMIT 20;Columns:
fingerprint(bigint) - Query identifierduration_ms(double precision) - Execution timequery_time(timestamptz) - When query ranapplication_name(text) - App that issued querydb_user(text) - Database userrows_processed(bigint) - Rows returned/affected
-- Get count of currently tracked queries
SELECT pgtrace_query_count();
-- Clear all query stats
SELECT pgtrace_reset();Identify which queries are failing and why. Tracks SQLSTATE codes for every error:
SELECT * FROM pgtrace_failing_queries
ORDER BY error_count DESC
LIMIT 20;Columns:
fingerprint(bigint) - Query identifiererror_code(text) - SQLSTATE (e.g., "23505" for unique violation)error_count(bigint) - Number of failureslast_error_at(timestamptz) - Last failure timestamp
Directly answers: "Which query keeps breaking and why?"
SELECT * FROM pgtrace_metrics;Columns:
queries_total(bigint)queries_failed(bigint)slow_queries(bigint)
SELECT * FROM pgtrace_latency_histogram;Columns:
bucket_upper_ms(int, NULL means >500ms)count(bigint)
SHOW pgtrace.enabled;
SHOW pgtrace.slow_query_ms;Defaults:
pgtrace.enabled = onpgtrace.slow_query_ms = 200
- Server fails to start after enabling: ensure the extension requests shared memory via
shmem_request_hook(required in PostgreSQL 15+). - MODULE_PATHNAME errors: ensure
module_pathname = '$libdir/pgtrace'is set inpgtrace.controland the extension is reinstalled. - Missing views: recreate the extension after SQL changes.
make clean
make
sudo make install
sudo systemctl restart postgresql@16-mainStable and functional for basic aggregate metrics. Contributions welcome for additional features (reset function, Prometheus output, per-user/db breakdowns).
This repository includes the following project files:
- License:
LICENSE(MIT) - Contribution guide:
CONTRIBUTING.md - Code of Conduct:
CODE_OF_CONDUCT.md - Security policy:
SECURITY.md - Changelog:
CHANGELOG.md