pg_plan_cache Agent
Manage, monitor, and diagnose the pg_plan_cache PostgreSQL extension. The Normalizer and Architecture tabs work without any backend. All other tabs require PostgreSQL and Redis credentials set as environment variables.
Status: Demo mode (no backend)
Normalize a SQL query and compute its SHA-256 cache key.
Live cache hit/miss/error statistics from pg_plan_cache_stats().
Cache efficiency analysis with tuning recommendations.
Full diagnostic: PostgreSQL, Redis, stats, and configuration.
Redis connectivity, memory, and keyspace info.
List cached plan keys stored in Redis.
View details of a specific cached plan by hash.
Explore bidirectional dependency mappings between queries and tables.
View current GUC parameter values for pg_plan_cache.
Invalidate cached plans. Leave table name empty to invalidate ALL plans.
Execute a read-only SELECT query against PostgreSQL.
pg_plan_cache — Architecture
How It Works
Query arrives at PostgreSQL
│
▼
┌─────────────────────────┐
│ planner_hook │ ← pgpc_planner_hook()
│ intercepts planning │
└────────┬────────────────┘
│
▼
┌─────────────────────────┐
│ normalize_query() │ Replace literals with $N
│ compute_query_hash() │ SHA-256 of normalized query
└────────┬────────────────┘
│
▼
┌─────────────────────────┐ ┌──────────────┐
│ Redis GET plan:<hash> │────▶│ Cache HIT? │
└────────┬────────────────┘ └──────┬───────┘
│ │
Cache MISS Return cached
│ PlannedStmt
▼
┌─────────────────────────┐
│ standard_planner() │ Run PostgreSQL planner
└────────┬────────────────┘
│
▼
┌─────────────────────────┐
│ serialize + Redis SET │ Store plan with TTL
│ extract_table_names() │ Track dependencies
│ redis_set_dependencies()│ Bidirectional mapping
└─────────────────────────┘
Key Components
| Component | File | Purpose |
|---|---|---|
| Planner Hook | pg_plan_cache.c |
Intercepts queries, checks cache, stores plans |
| Query Normalizer | query_normalize.c |
Literals → $N, collapse whitespace, lowercase |
| Redis Client | redis_client.c |
Connection pool, GET/SET/DEL, dependency tracking |
| Schema Invalidation | pg_plan_cache.c |
Relcache callback bumps version on DDL |
Redis Key Patterns
| Pattern | Purpose |
|---|---|
plan:<sha256> |
Serialized PlannedStmt + metadata |
deps:table:<schema.table> |
SET of query hashes depending on this table |
qdeps:<sha256> |
SET of table names this query depends on |
GUC Parameters
| Parameter | Default | Restart? |
|---|---|---|
pg_plan_cache.redis_host |
127.0.0.1 | No (SIGHUP) |
pg_plan_cache.redis_port |
6379 | No (SIGHUP) |
pg_plan_cache.ttl |
3600 | No (SIGHUP) |
pg_plan_cache.enabled |
true | No (SUSET) |
pg_plan_cache.redis_timeout_ms |
500 | No (SIGHUP) |
pg_plan_cache.redis_pool_size |
4 | Yes (POSTMASTER) |
Serialization Format
schema_version|total_cost|unix_timestamp|nodeToString(PlannedStmt)
Plans with a stale schema_version are discarded on read.
Normalization Examples
| Input | Normalized |
|---|---|
SELECT * FROM users WHERE id = 42 |
select * from users where id = $1 |
SELECT name FROM t WHERE x = 'hello' |
select name from t where x = $1 |
SELECT /* comment */ a FROM b |
select a from b |