https://github.com/pgx-contrib/pgxprof
Query profiler for pgx v5 — drop-in tracer that captures EXPLAIN (ANALYZE, FORMAT JSON) plans via inline SQL annotations and a pluggable Reporter interface
https://github.com/pgx-contrib/pgxprof
explain-analyze go golang pgx pgxpool postgresql profiler query-plan query-profiler tracing
Last synced: 27 days ago
JSON representation
Query profiler for pgx v5 — drop-in tracer that captures EXPLAIN (ANALYZE, FORMAT JSON) plans via inline SQL annotations and a pluggable Reporter interface
- Host: GitHub
- URL: https://github.com/pgx-contrib/pgxprof
- Owner: pgx-contrib
- License: mit
- Created: 2024-09-20T13:05:00.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2026-06-06T08:02:34.000Z (about 1 month ago)
- Last Synced: 2026-06-06T10:05:16.497Z (about 1 month ago)
- Topics: explain-analyze, go, golang, pgx, pgxpool, postgresql, profiler, query-plan, query-profiler, tracing
- Language: Go
- Homepage: https://pkg.go.dev/github.com/pgx-contrib/pgxprof
- Size: 76.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# pgxprof
[](https://github.com/pgx-contrib/pgxprof/actions/workflows/ci.yml)
[](https://github.com/pgx-contrib/pgxprof/releases)
[](https://pkg.go.dev/github.com/pgx-contrib/pgxprof)
[](LICENSE)
[](go.mod)
[](https://github.com/jackc/pgx)
Query profiler for [pgx v5](https://github.com/jackc/pgx).
## Features
- Transparent `EXPLAIN (ANALYZE, FORMAT JSON)` wrapping for `Query`, `QueryRow`, and `SendBatch`
- Inline SQL annotation directives control profiling per query
- Decoded `QueryPlan` / `QueryTrace` Go structs ready for further processing
- Pluggable `Reporter` interface with built-in JSON writer and `log/slog` sinks
- Works with any `pgx`-compatible connection: `*pgx.Conn`, `*pgxpool.Pool`, or `pgx.Tx`
## Installation
```bash
go get github.com/pgx-contrib/pgxprof
```
## Usage
### Basic pool setup
```go
config, err := pgxpool.ParseConfig(os.Getenv("PGX_DATABASE_URL"))
if err != nil {
panic(err)
}
config.ConnConfig.Tracer = &pgxprof.QueryTracer{
// Default options applied when a query has no inline annotations.
Options: &pgxprof.QueryOptions{
Explain: true,
Analyze: true,
},
// Defaults to a WriterReporter that prints JSON to stdout.
Reporter: &pgxprof.LoggerReporter{Logger: slog.Default()},
}
pool, err := pgxpool.NewWithConfig(ctx, config)
```
### Per-query annotations
Embed profiler directives in SQL comments. Annotations override the default `Options` for that statement:
```sql
-- @explain true
-- @analyze true
SELECT id, name FROM users WHERE active = true
```
```go
rows, err := pool.Query(ctx, `
-- @explain true
-- @analyze true
SELECT id, name FROM users WHERE active = $1`, true)
```
### Custom reporter
Implement the `Reporter` interface to ship traces anywhere:
```go
type Reporter interface {
Report(ctx context.Context, trace *TraceQueryData)
ReportBatch(ctx context.Context, trace *TraceBatchData)
}
```
## Annotation directives
| Directive | Value | Description |
|---|---|---|
| `@explain` | `true` / `false` | Wrap the query in `EXPLAIN`. Required for profiling. |
| `@analyze` | `true` / `false` | Add the `ANALYZE` clause. Ignored when `@explain` is `false`. |
## Performance caveat
`EXPLAIN ANALYZE` **executes the query** inside a transaction that `pgxprof`
rolls back, so profiling runs every matching statement twice: once for the
caller and once for the plan. This roughly doubles per-query latency and
database load.
Use `pgxprof` in development and staging environments, or gate it behind
per-query directives so only the queries you're investigating pay the cost.
## Development
### DevContainer
Open in VS Code with the Dev Containers extension. The environment provides Go,
PostgreSQL 18, and Nix automatically.
```
PGX_DATABASE_URL=postgres://vscode@postgres:5432/pgxprof?sslmode=disable
```
### Nix
```bash
nix develop # enter shell with Go
go tool ginkgo run -r
```
### Run tests
```bash
# Unit tests only (no database required)
go tool ginkgo run -r
# With integration tests
export PGX_DATABASE_URL="postgres://localhost/pgxprof?sslmode=disable"
go tool ginkgo run -r
```
## License
[MIT](LICENSE)