Quickstart
Prerequisites
Section titled “Prerequisites”- PostgreSQL 15 or later (server headers required)
pg_configin yourPATH- A C compiler (
gccorclang)
Installation
Section titled “Installation”-
Clone the repository
Terminal window git clone https://github.com/samsiva-dev/pg_ext_memcheck.gitcd pg_ext_memcheck -
Build and install
Terminal window makesudo make installThis uses PGXS to build against your installed PostgreSQL headers and places the extension files in the correct
$libdir. -
Configure
postgresql.confAdd the extension to the preloaded libraries so the background worker and hooks are registered at startup:
# postgresql.confshared_preload_libraries = 'pg_ext_memcheck'Restart PostgreSQL after making this change.
-
Create the extension
CREATE EXTENSION pg_ext_memcheck;
Your first check
Section titled “Your first check”Test a simple function or query from/on any extension you are developing:
-- Set the monitoring mode (controls which execution phases are instrumented)SET pg_ext_memcheck.memcheck_mode = 'executor';
-- Start a check window targeted at your extension's memory contexts.-- The pattern uses SQL LIKE syntax; '%' is a wildcard.-- Pass an empty string to monitor all contexts.SELECT ext_memcheck.begin('MyExtCtx%');
-- Call the function you want to inspectSELECT your_extension.some_function('input');
-- End the window; returns violations for contexts matching 'MyExtCtx%'SELECT * FROM ext_memcheck.end();
-- Also flush any remaining ring-buffer entries to the log tableSELECT ext_memcheck.flush_violations();
-- Query the violation log for detailsSELECT * FROM ext_memcheck.violation_log ORDER BY ts DESC;If flush_violations() returns zero rows, no leaks or wrong-context allocations were detected for that invocation.
To suppress false positives from contexts your extension intentionally uses long-term, pass an allowed_contexts allowlist:
SET pg_ext_memcheck.memcheck_mode = 'all';SELECT ext_memcheck.begin( 'MyExtCtx%', '{"allowed_contexts": ["TopMemoryContext", "CacheMemoryContext"]}');SELECT your_extension.some_function('input');SELECT * FROM ext_memcheck.end();A violation row looks like this:
| Column | Example |
|---|---|
ts | 2026-05-10 14:32:01 UTC |
backend_pid | 12345 |
detail | "Context present in post-query snapshot but not pre-query" |
severity | WARNING, INFO, ERROR |
check_type | context_leak, wrong_ctx_alloc, shmem_overrun, etc. |
source_lib | your_extension.dylib |
Run a built-in stress scenario
Section titled “Run a built-in stress scenario”-- Run the growth benchmark scenario (measures context growth over repeated calls)SELECT ext_memcheck.run_scenario('growth_benchmark', 100, 'SELECT your_extension.some_function(''input'');');
SELECT ext_memcheck.flush_violations();-- Run the tx_abort_loop scenario (tests memory cleanup on transaction abort)SELECT ext_memcheck.run_scenario('tx_abort_loop', 50, 'SELECT your_extension.some_function(''input'');');
SELECT ext_memcheck.flush_violations();GUC parameters
Section titled “GUC parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
pg_ext_memcheck.memcheck_mode | enum | none | all / executor / none — controls which execution phases are hooked. See API reference. |
pg_ext_memcheck.min_leak_bytes | int | 8192 | Context growth smaller than this (in bytes) is silently ignored by the leak detector. |
pg_ext_memcheck.bloat_min_bytes | int | 8192 | Minimum cumulative growth (in bytes) for a context to be reported as bloating by growth_benchmark. |
memcheck_mode controls which phases are hooked; the ext_context_pattern argument to begin() controls which contexts are reported. Set the GUC once for the session:
-- Executor-only mode (less noise, skips planning-phase allocations)SET pg_ext_memcheck.memcheck_mode = 'executor';
-- Full coverage: planner + executorSET pg_ext_memcheck.memcheck_mode = 'all';Regression testing
Section titled “Regression testing”The pg_ext_memcheck extension includes a test suite that can be run using pg_regress (comes with PostgreSQL source). To run the tests:
From the extension directory, run:
PG_CONFIG=pg_config ./test/run_tests.sh