Postgres patterns
Skill Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack/plugins/devtools-pack/skills/postgres-patterns
A curated pack of custom Claude Code skills for developers — installable as a Claude Code plugin marketplace.
npx -y skills add Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack --skill postgres-patternsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
When to activate: PostgreSQL, JSONB, pg, psql, indexes, CTEs, window functions, partitioning, VACUUM, pg_stat, postgres
SKILL.md
4.2 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
PostgreSQL Patterns
JSONB Queries
-- JSONB containment and path operators
SELECT * FROM events WHERE payload @> '{"type": "click"}';
SELECT payload->>'user_id' AS user_id FROM events;
SELECT payload#>>'{meta,source}' AS source FROM events;
-- JSONB indexes
CREATE INDEX idx_events_payload_gin ON events USING GIN (payload);
CREATE INDEX idx_events_type ON events ((payload->>'type'));
-- JSONB update
UPDATE events SET payload = payload || '{"processed": true}' WHERE id = 1;
UPDATE events SET payload = payload - 'temp_field';
Index Types
-- B-tree (default) — equality & range
CREATE INDEX ON orders (created_at DESC);
-- GIN — JSONB, arrays, full-text
CREATE INDEX ON articles USING GIN (to_tsvector('english', body));
CREATE INDEX ON products USING GIN (tags);
-- GiST — geometric, range types, full-text
CREATE INDEX ON locations USING GIST (coordinates);
CREATE INDEX ON reservations USING GIST (during); -- tsrange
-- BRIN — large sequential tables (logs, time-series)
CREATE INDEX ON logs USING BRIN (created_at) WITH (pages_per_range = 128);
-- Partial index
CREATE INDEX ON orders (user_id) WHERE status = 'pending';
-- Covering index (INCLUDE)
CREATE INDEX ON orders (user_id) INCLUDE (total, status);
CTEs and Window Functions
-- Recursive CTE (org hierarchy)
WITH RECURSIVE org AS (
SELECT id, name, manager_id, 0 AS depth
FROM employees WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id, o.depth + 1
FROM employees e JOIN org o ON e.manager_id = o.id
)
SELECT * FROM org ORDER BY depth;
-- Window functions
SELECT
user_id,
amount,
SUM(amount) OVER (PARTITION BY user_id ORDER BY created_at
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total,
RANK() OVER (PARTITION BY user_id ORDER BY amount DESC) AS rank,
LAG(amount) OVER (PARTITION BY user_id ORDER BY created_at) AS prev_amount
FROM transactions;
-- DISTINCT ON (keep first per group)
SELECT DISTINCT ON (user_id) user_id, status, created_at
FROM orders ORDER BY user_id, created_at DESC;
Partitioning
-- Range partitioning by month
CREATE TABLE events (
id BIGSERIAL,
created_at TIMESTAMPTZ NOT NULL,
payload JSONB
) PARTITION BY RANGE (created_at);
CREATE TABLE events_2024_01 PARTITION OF events
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
-- Auto-create partitions with pg_partman
SELECT partman.create_parent('public.events', 'created_at', 'native', 'monthly');
VACUUM and Maintenance
-- Check bloat
SELECT relname, n_dead_tup, n_live_tup,
round(n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0) * 100, 2) AS dead_pct
FROM pg_stat_user_tables ORDER BY n_dead_tup DESC;
-- Force vacuum analyze
VACUUM (ANALYZE, VERBOSE) orders;
-- Check autovacuum settings per table
ALTER TABLE orders SET (autovacuum_vacuum_scale_factor = 0.01);
pg_stat Queries
-- Slow queries
SELECT query, calls, total_exec_time/calls AS avg_ms,
rows/calls AS avg_rows
FROM pg_stat_statements
ORDER BY total_exec_time DESC LIMIT 20;
-- Index usage
SELECT relname, indexrelname, idx_scan, idx_tup_fetch
FROM pg_stat_user_indexes ORDER BY idx_scan ASC;
-- Table sizes
SELECT relname,
pg_size_pretty(pg_total_relation_size(relid)) AS total_size
FROM pg_stat_user_tables ORDER BY pg_total_relation_size(relid) DESC;
-- Active connections
SELECT state, count(*) FROM pg_stat_activity GROUP BY state;
-- Blocking queries
SELECT pid, query, wait_event_type, wait_event
FROM pg_stat_activity WHERE wait_event IS NOT NULL;
Performance Tips
- Use
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)for detailed plans - Set
work_memper session for sort-heavy queries:SET work_mem = '256MB' - Use
connection_limiton roles,PgBouncerfor pooling shared_buffers= 25% RAM;effective_cache_size= 75% RAM- Prefer
COPYoverINSERTfor bulk loads - Use
UNLOGGED TABLEfor ephemeral staging data
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.