{"id":"bd3c2529-c63e-4b5e-beba-b1901cf140df","shortId":"tZNGGf","kind":"skill","title":"postgres","tagline":"Auto-activate for .sql files, psql commands, postgresql.conf, psycopg/asyncpg imports. Produces PostgreSQL queries, PL/pgSQL functions, indexing strategies, and connection patterns. Use when: writing PostgreSQL queries, optimizing performance, managing security/roles/RLS, configu","description":"# PostgreSQL\n\nPostgreSQL is an advanced open-source relational database with extensive support for SQL standards, JSONB, full-text search, PL/pgSQL, and extensibility.\n\n## Quick Reference\n\n### Connection Patterns\n\n```bash\n# URI format\n\"postgresql://app:secret@localhost:5432/mydb?sslmode=require&application_name=myapp\"\n\n# Multiple hosts (failover)\n\"postgresql://app:secret@primary:5432,standby:5432/mydb?target_session_attrs=read-write\"\n```\n\n```python\n# asyncpg (async)\npool = await asyncpg.create_pool(\"postgresql://app:secret@localhost/mydb\", min_size=5, max_size=20)\nasync with pool.acquire() as conn:\n    rows = await conn.fetch(\"SELECT id, name FROM users WHERE status = $1\", \"active\")\n\n# psycopg v3 (async)\nasync with await psycopg.AsyncConnection.connect(conninfo) as conn:\n    async with conn.cursor() as cur:\n        await cur.execute(\"SELECT id, name FROM users WHERE id = %s\", (42,))\n```\n\n### Indexing Essentials\n\n| Type | Best For | Example |\n|------|----------|---------|\n| B-tree (default) | Equality, range on scalars | `CREATE INDEX idx ON orders (created_at DESC)` |\n| GIN | JSONB, arrays, full-text, trigram | `CREATE INDEX idx ON docs USING gin (data)` |\n| GiST | Geometry, range types, nearest-neighbor | `CREATE INDEX idx ON events USING gist (during)` |\n| BRIN | Large, naturally ordered (time-series) | `CREATE INDEX idx ON logs USING brin (ts)` |\n\n**Partial indexes** -- index only the rows that matter:\n\n```sql\nCREATE INDEX idx_orders_active ON orders (user_id)\n WHERE status IN ('pending', 'processing');\n```\n\n### Key JSONB Patterns\n\n```sql\n-- Navigation\nSELECT data->>'name' FROM docs;             -- text extraction\nSELECT data @> '{\"status\": \"active\"}' FROM docs;  -- containment\n\n-- GIN index for containment\nCREATE INDEX idx_docs_data ON docs USING gin (data jsonb_path_ops);\n\n-- Build objects\nSELECT jsonb_build_object('id', u.id, 'name', u.name) FROM users u;\n```\n\n### EXPLAIN Usage\n\n```sql\n-- Full diagnostic\nEXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT ...;\n\n-- Safe for mutating queries (no execution)\nEXPLAIN (COSTS, VERBOSE) DELETE FROM orders WHERE created_at < '2020-01-01';\n```\n\n| Symptom | Likely Cause | Fix |\n|---------|-------------|-----|\n| `Seq Scan` on large table | Missing/unused index | Create index, check predicate |\n| `Sort Method: external merge Disk` | `work_mem` too low | Increase `work_mem` |\n| High `Rows Removed by Filter` | Index not selective | Refine index, add partial index |\n\n<workflow>\n\n## Workflow\n\n### Step 1: Schema Design\n\nDefine tables with appropriate types. Use JSONB for semi-structured data, arrays for small sets, and normalized tables for relational data. Always define primary keys.\n\n### Step 2: Write Queries\n\nUse parameterized queries (`$1` for asyncpg, `%s` for psycopg). Use CTEs for readability. Prefer `EXISTS` over `IN` for correlated subqueries.\n\n### Step 3: Index Strategy\n\nStart with B-tree indexes on WHERE/JOIN/ORDER BY columns. Use partial indexes to limit index size. Add GIN indexes for JSONB containment queries. Prefer expression indexes for computed predicates.\n\n### Step 4: Performance Tuning\n\nRun `EXPLAIN (ANALYZE, BUFFERS)` on slow queries. Check `pg_stat_statements` for top queries by total time. Tune `shared_buffers`, `work_mem`, and autovacuum settings.\n\n### Step 5: Validate\n\nConfirm EXPLAIN plans use indexes. Check `pg_stat_user_tables` for sequential scan counts on large tables. Verify connection pooling (pgbouncer) is configured for production.\n\n</workflow>\n\n<guardrails>\n\n## Guardrails\n\n- **Always use parameterized queries** -- never interpolate user input. Use `$1` placeholders (asyncpg) or `%s` (psycopg).\n- **Prefer partial indexes** -- indexing only relevant rows reduces size and improves write performance.\n- **EXPLAIN before optimizing** -- always measure before adding indexes or rewriting queries. Use `EXPLAIN (ANALYZE, BUFFERS)` for real execution stats.\n- **Use JSONB, not JSON** -- JSONB is decomposed binary, supports GIN indexing and operators. Plain JSON is only for exact text preservation.\n- **Connection pooling in production** -- use pgbouncer or built-in pool. Never open unbounded connections from application servers.\n- **pg_stat_statements for production monitoring** -- identifies top queries by time, calls, and cache hit ratio.\n- **Avoid `SELECT *`** -- name columns to enable covering indexes and prevent schema-change breakage.\n\n</guardrails>\n\n<validation>\n\n### Validation Checkpoint\n\nBefore delivering PostgreSQL code, verify:\n\n- [ ] All queries use parameterized placeholders (no string interpolation)\n- [ ] EXPLAIN output confirms index usage for critical queries\n- [ ] Partial indexes are used where only a subset of rows is queried\n- [ ] JSONB columns use GIN indexes for containment queries\n- [ ] Connection pooling is addressed (pgbouncer or pool parameter)\n- [ ] sslmode is set to at least `require` for non-local connections\n\n</validation>\n\n<example>\n\n## Example\n\n**Task:** EXPLAIN ANALYZE and index optimization for a slow orders query.\n\n```sql\n-- Step 1: Check current plan\nEXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)\nSELECT o.id, o.total, o.created_at, u.name\n  FROM orders o\n  JOIN users u ON u.id = o.user_id\n WHERE o.status = 'pending'\n   AND o.created_at > NOW() - INTERVAL '7 days'\n ORDER BY o.created_at DESC\n LIMIT 50;\n\n-- Step 2: If Seq Scan on orders, add a partial composite index\nCREATE INDEX CONCURRENTLY idx_orders_pending_recent\n    ON orders (created_at DESC)\n WHERE status = 'pending';\n\n-- Step 3: Re-run EXPLAIN to confirm Index Scan\nEXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)\nSELECT o.id, o.total, o.created_at, u.name\n  FROM orders o\n  JOIN users u ON u.id = o.user_id\n WHERE o.status = 'pending'\n   AND o.created_at > NOW() - INTERVAL '7 days'\n ORDER BY o.created_at DESC\n LIMIT 50;\n\n-- Step 4: Check pg_stat_statements for overall impact\nSELECT calls, round(mean_exec_time::numeric, 1) AS mean_ms, query\n  FROM pg_stat_statements\n ORDER BY total_exec_time DESC\n LIMIT 10;\n```\n\n</example>\n\n---\n\n## Monitoring Strategy\n\n### pg_stat_statements Setup\n\nEnable in `postgresql.conf` (requires restart):\n\n```ini\nshared_preload_libraries = 'pg_stat_statements'\npg_stat_statements.track = all\npg_stat_statements.max = 10000\n```\n\n```sql\nCREATE EXTENSION IF NOT EXISTS pg_stat_statements;\n```\n\n### Key pg_stat_statements Queries\n\n```sql\n-- Top queries by total execution time\nSELECT\n    round(total_exec_time::numeric, 1) AS total_ms,\n    calls,\n    round(mean_exec_time::numeric, 1)  AS mean_ms,\n    round(stddev_exec_time::numeric, 1) AS stddev_ms,\n    round((100 * total_exec_time / sum(total_exec_time) OVER ())::numeric, 1) AS pct,\n    left(query, 120) AS query\nFROM pg_stat_statements\nORDER BY total_exec_time DESC\nLIMIT 20;\n\n-- Top queries by average latency (outliers)\nSELECT\n    calls,\n    round(mean_exec_time::numeric, 2) AS mean_ms,\n    left(query, 120) AS query\nFROM pg_stat_statements\nWHERE calls > 100\nORDER BY mean_exec_time DESC\nLIMIT 20;\n\n-- Cache hit ratio per query\nSELECT\n    calls,\n    round(100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0), 1) AS cache_hit_pct,\n    left(query, 120) AS query\nFROM pg_stat_statements\nORDER BY shared_blks_read DESC\nLIMIT 20;\n\n-- Reset stats\nSELECT pg_stat_statements_reset();\n```\n\n### Sequential Scan Detection (pg_stat_user_tables)\n\n```sql\n-- Tables with high sequential scan counts\nSELECT\n    schemaname,\n    relname AS table_name,\n    seq_scan,\n    seq_tup_read,\n    idx_scan,\n    round(100.0 * seq_scan / nullif(seq_scan + idx_scan, 0), 1) AS seq_pct,\n    n_live_tup\nFROM pg_stat_user_tables\nWHERE seq_scan > 0\n  AND n_live_tup > 10000\nORDER BY seq_scan DESC\nLIMIT 20;\n```\n\n### Bloat Detection\n\n```sql\n-- Table bloat estimate\nSELECT\n    schemaname,\n    tablename,\n    pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename)) AS total_size,\n    n_dead_tup,\n    n_live_tup,\n    round(100.0 * n_dead_tup / nullif(n_live_tup + n_dead_tup, 0), 1) AS dead_pct,\n    last_autovacuum,\n    last_autoanalyze\nFROM pg_stat_user_tables\nWHERE n_dead_tup > 1000\nORDER BY n_dead_tup DESC\nLIMIT 20;\n\n-- Index bloat (using pg_relation_size vs estimated used)\nSELECT\n    indexrelname,\n    pg_size_pretty(pg_relation_size(indexrelid)) AS index_size,\n    idx_scan,\n    idx_tup_read,\n    idx_tup_fetch\nFROM pg_stat_user_indexes\nORDER BY pg_relation_size(indexrelid) DESC\nLIMIT 20;\n```\n\n### Active Query Monitoring (pg_stat_activity)\n\n```sql\n-- Long-running queries\nSELECT\n    pid,\n    now() - query_start AS duration,\n    state,\n    wait_event_type,\n    wait_event,\n    left(query, 100) AS query\nFROM pg_stat_activity\nWHERE state != 'idle'\n  AND query_start < now() - INTERVAL '30 seconds'\nORDER BY duration DESC;\n\n-- Blocking and blocked queries\nSELECT\n    blocked.pid          AS blocked_pid,\n    blocking.pid         AS blocking_pid,\n    left(blocked.query, 80)  AS blocked_query,\n    left(blocking.query, 80) AS blocking_query\nFROM pg_stat_activity blocked\nJOIN pg_stat_activity blocking\n  ON blocking.pid = ANY(pg_blocking_pids(blocked.pid))\nWHERE cardinality(pg_blocking_pids(blocked.pid)) > 0;\n\n-- Terminate a specific pid (superuser only)\nSELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid = <target_pid>;\n```\n\n---\n\n## Autovacuum Tuning\n\n### Per-Table Settings\n\nOverride global autovacuum settings for high-churn tables:\n\n```sql\n-- High-churn table: trigger vacuum more aggressively\nALTER TABLE orders SET (\n    autovacuum_vacuum_scale_factor     = 0.01,   -- 1% dead tuples (default 20%)\n    autovacuum_analyze_scale_factor    = 0.005,  -- 0.5% changed for analyze\n    autovacuum_vacuum_cost_delay       = 2,      -- ms; lower = faster vacuum\n    autovacuum_vacuum_threshold        = 50,     -- minimum dead tuples before trigger\n    autovacuum_analyze_threshold       = 50\n);\n\n-- Large append-only table: raise threshold to reduce noise\nALTER TABLE events SET (\n    autovacuum_vacuum_scale_factor  = 0.001,\n    autovacuum_analyze_scale_factor = 0.001\n);\n```\n\n### Dead Tuple Threshold Formula\n\nAutovacuum triggers when:\n\n```text\ndead_tuples > autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * n_live_tup\n```\n\nFor a 10M-row table at the default `scale_factor=0.20`:\n\n- Threshold = 50 + 0.20 × 10,000,000 = **2,000,050 dead tuples** before vacuum runs.\n- Reduce `scale_factor` to `0.01` for tables with frequent UPDATE/DELETE.\n\n### Global postgresql.conf Tuning\n\n```ini\n# Reduce I/O impact of autovacuum\nautovacuum_vacuum_cost_delay = 2ms          # default 2ms (pg14+); was 20ms\nautovacuum_vacuum_cost_limit = 400          # default 200; allows faster passes\n\n# Scale factor defaults (override per-table for hot tables)\nautovacuum_vacuum_scale_factor  = 0.05     # default 0.20\nautovacuum_analyze_scale_factor = 0.02     # default 0.10\n\n# Worker count\nautovacuum_max_workers = 5                  # default 3\n```\n\n---\n\n## Connection Pooling\n\n### PgBouncer vs pgpool-II\n\n| Feature | PgBouncer | pgpool-II |\n|---------|-----------|-----------|\n| Primary purpose | Connection pooling | Pooling + load balancing + HA |\n| Modes | Session, Transaction, Statement | Session, Transaction |\n| Overhead | Very low (C, single process) | Higher (more features) |\n| Read scaling | No built-in | Routes SELECTs to replicas |\n| HA / failover | No (use external) | Yes (watchdog, VIP) |\n| Complexity | Simple config | More complex |\n| Typical use | Application → single primary | Need query routing or HA middleware |\n\n### PgBouncer Configuration (pgbouncer.ini)\n\n```ini\n[databases]\nmydb = host=127.0.0.1 port=5432 dbname=mydb\n\n[pgbouncer]\nlisten_port        = 6432\nlisten_addr        = 0.0.0.0\nauth_type          = scram-sha-256\nauth_file          = /etc/pgbouncer/userlist.txt\npool_mode          = transaction        ; transaction mode = best performance\nmax_client_conn    = 1000\ndefault_pool_size  = 25\nmin_pool_size      = 5\nreserve_pool_size  = 5\nreserve_pool_timeout = 3\nserver_idle_timeout = 600\nlog_connections    = 0\nlog_disconnections = 0\n```\n\n### Transaction vs Session Mode\n\n| Mode | Behaviour | Use Case |\n|------|-----------|----------|\n| **Transaction** | Server connection held only during transaction | Stateless apps; highest concurrency |\n| **Session** | Server connection held for full client session | Requires session state (temp tables, prepared statements) |\n| **Statement** | Released after each statement | Rarely used; autocommit only |\n\n**Transaction mode caveat:** prepared statements and advisory locks are incompatible with transaction mode. Disable `prepared_statements` at the driver level or use `DEALLOCATE ALL` at transaction end.\n\n---\n\n## Cross-References\n\n- **Gemini PostgreSQL extension**: `gemini extensions install https://github.com/gemini-cli-extensions/postgresql` — 24 tools for query execution, schema inspection, EXPLAIN analysis, and more.\n\n---\n\n## References Index\n\nFor detailed guides and code examples, refer to the following documents in `references/`:\n\n- **[Advanced SQL Patterns](references/queries.md)** -- CTEs, window functions, JSONB operations, array ops, lateral joins, recursive queries.\n- **[Indexing & Performance](references/indexing.md)** -- Index types (B-tree, GIN, GiST, BRIN), partial indexes, expression indexes.\n- **[Administration](references/admin.md)** -- Configuration, roles, connection pooling (pgbouncer), vacuuming, WAL.\n- **[psql CLI](references/psql.md)** -- psql commands, \\d meta-commands, .psqlrc customization.\n- **[PL/pgSQL Development](references/plpgsql.md)** -- Functions, procedures, triggers, exception handling, DO blocks.\n- **[Performance Tuning](references/performance.md)** -- EXPLAIN, pg_stat_statements, autovacuum, parallel query.\n- **[Connection Patterns](references/connections.md)** -- psycopg v3, asyncpg, SQLAlchemy, node-postgres, Rust sqlx.\n- **[JSON/JSONB Patterns](references/json.md)** -- JSONB operators, SQL/JSON path, GIN indexing, generated columns.\n- **[Security](references/security.md)** -- Role management, RLS, column privileges, SSL/TLS, pgAudit.\n- **[Key Extensions](references/extensions.md)** -- PostGIS, pgvector, pg_cron, pg_stat_statements, pg_trgm, TimescaleDB.\n- **[Replication & HA](references/replication.md)** -- Streaming replication, logical replication, Patroni, PITR.\n- **[Schema Migrations & DevOps](references/migrations.md)** -- Alembic, Flyway, zero-downtime migrations, pgTAP testing.\n\n---\n\n## Official References\n\n- <https://www.postgresql.org/docs/current/>\n- <https://wiki.postgresql.org/>\n\n## Shared Styleguide Baseline\n\n- Use shared styleguides for generic language/framework rules to reduce duplication in this skill.\n- [General Principles](https://github.com/cofin/flow/blob/main/templates/styleguides/general.md)\n- [PostgreSQL](https://github.com/cofin/flow/blob/main/templates/styleguides/databases/postgres_psql.md)\n- Keep this skill focused on tool-specific workflows, edge cases, and integration details.","tags":["postgres","flow","cofin","agent-skills","ai-agents","beads","claude-code","codex","cursor","developer-tools","gemini-cli","opencode"],"capabilities":["skill","source-cofin","skill-postgres","topic-agent-skills","topic-ai-agents","topic-beads","topic-claude-code","topic-codex","topic-cursor","topic-developer-tools","topic-gemini-cli","topic-opencode","topic-plugin","topic-slash-commands","topic-spec-driven-development"],"categories":["flow"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cofin/flow/postgres","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cofin/flow","source_repo":"https://github.com/cofin/flow","install_from":"skills.sh"}},"qualityScore":"0.455","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 11 github stars · SKILL.md body (14,809 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-24T07:03:19.159Z","embedding":null,"createdAt":"2026-04-23T13:04:00.712Z","updatedAt":"2026-04-24T07:03:19.159Z","lastSeenAt":"2026-04-24T07:03:19.159Z","tsv":"'-01':313,314 '/cofin/flow/blob/main/templates/styleguides/databases/postgres_psql.md)':1939 '/cofin/flow/blob/main/templates/styleguides/general.md)':1935 '/docs/current/':1913 '/etc/pgbouncer/userlist.txt':1627 '/gemini-cli-extensions/postgresql':1746 '0':1004,1070,1086,1138,1303,1661,1664 '0.0.0.0':1618 '0.001':1408,1413 '0.005':1363 '0.01':1353,1464 '0.02':1520 '0.05':1513 '0.10':1522 '0.20':1445,1448,1515 '0.5':1364 '000':1450,1451,1453 '050':1454 '1':119,357,393,511,695,828,894,904,913,928,1005,1071,1139,1354 '10':844,1449 '100':918,976,1234 '100.0':993,1062,1127 '1000':1156,1638 '10000':866,1091 '10m':1437 '10m-row':1436 '120':933,967,1012 '127.0.0.1':1607 '2':387,738,961,1372,1452 '20':103,947,984,1026,1098,1164,1207,1358 '200':1495 '2020':312 '20ms':1488 '24':1747 '25':1642 '256':1624 '2ms':1483,1485 '3':411,765,1530,1654 '30':1249 '4':445,813 '400':1493 '42':146 '5':100,474,1528,1646,1650 '50':736,811,1380,1389,1447 '5432':79,1609 '5432/mydb':67,81 '600':1658 '6432':1615 '7':728,803 '80':1270,1276 'activ':4,120,227,252,1208,1213,1240,1283,1288,1318 'ad':536 'add':352,431,744 'addr':1617 'address':664 'administr':1803 'advanc':37,1773 'advisori':1714 'aggress':1344 'alemb':1901 'allow':1496 'alter':1345,1400 'alway':382,502,533 'analysi':1755 'analyz':292,450,543,684,700,775,1360,1367,1387,1410,1517 'app':64,76,95,1681 'append':1392 'append-on':1391 'applic':70,586,1591 'appropri':363 'array':171,372,1782 'async':90,104,123,124,131 'asyncpg':89,395,513,1848 'asyncpg.create':93 'attr':84 'auth':1619,1625 'auto':3 'auto-activ':2 'autoanalyz':1146 'autocommit':1706 'autovacuum':471,1144,1321,1329,1349,1359,1368,1377,1386,1404,1409,1418,1424,1427,1478,1479,1489,1509,1516,1525,1840 'averag':951 'avoid':604 'await':92,110,126,136 'b':154,417,1794 'b-tree':153,416,1793 'backend':1313 'balanc':1549 'baselin':1917 'bash':61 'behaviour':1670 'best':150,1633 'binari':556 'blks':995,999,1002,1022 'bloat':1099,1103,1166 'block':1255,1257,1262,1266,1272,1278,1284,1289,1294,1300,1832 'blocked.pid':1260,1296,1302 'blocked.query':1269 'blocking.pid':1264,1291 'blocking.query':1275 'breakag':617 'brin':199,212,1798 'buffer':293,451,467,544,701,776 'build':273,277 'built':578,1570 'built-in':577,1569 'c':1560 'cach':601,985,1007 'call':599,822,898,955,975,991 'cardin':1298 'case':1672,1950 'caus':317 'caveat':1710 'chang':616,1365 'check':328,455,481,696,814 'checkpoint':619 'churn':1334,1339 'cli':1813 'client':1636,1690 'code':623,1764 'column':423,607,654,1865,1871 'command':9,1816,1820 'complex':1584,1588 'composit':747 'comput':442 'concurr':751,1683 'config':1586 'configu':32 'configur':498,1601,1805 'confirm':476,635,771 'conn':108,130,1637 'conn.cursor':133 'conn.fetch':111 'connect':21,59,494,570,584,661,680,1531,1545,1660,1675,1686,1807,1843 'conninfo':128 'contain':255,259,436,659 'correl':408 'cost':304,1370,1481,1491 'count':489,1047,1524 'cover':610 'creat':161,166,176,191,206,223,260,310,326,749,758,868 'critic':639 'cron':1881 'cross':1736 'cross-refer':1735 'ctes':400,1777 'cur':135 'cur.execute':137 'current':697 'custom':1822 'd':1817 'data':183,243,250,264,269,371,381 'databas':42,1604 'day':729,804 'dbname':1610 'dead':1121,1129,1136,1141,1154,1160,1355,1382,1414,1422,1455 'dealloc':1730 'decompos':555 'default':156,1357,1442,1484,1494,1501,1514,1521,1529,1639 'defin':360,383 'delay':1371,1482 'delet':306 'deliv':621 'desc':168,734,760,809,842,945,982,1024,1096,1162,1205,1254 'design':359 'detail':1761,1953 'detect':1036,1100 'develop':1824 'devop':1899 'diagnost':290 'disabl':1721 'disconnect':1663 'disk':334 'doc':180,246,254,263,266 'document':1770 'downtim':1905 'driver':1726 'duplic':1927 'durat':1225,1253 'edg':1949 'enabl':609,851 'end':1734 'equal':157 'essenti':148 'estim':1104,1172 'event':195,1228,1231,1402 'exact':567 'exampl':152,681,1765 'except':1829 'exec':825,840,891,901,910,920,924,943,958,980 'execut':302,547,886,1751 'exist':404,872 'explain':286,291,303,449,477,530,542,633,683,699,769,774,1754,1836 'express':439,1801 'extens':44,56,869,1740,1742,1876 'extern':332,1580 'extract':248 'factor':1352,1362,1407,1412,1430,1444,1462,1500,1512,1519 'failov':75,1577 'faster':1375,1497 'featur':1538,1565 'fetch':1193 'file':7,1626 'filter':346 'fix':318 'flyway':1902 'focus':1943 'follow':1769 'format':63,294,702,777 'formula':1417 'frequent':1468 'full':51,173,289,1689 'full-text':50,172 'function':17,1779,1826 'gemini':1738,1741 'general':1931 'generat':1864 'generic':1922 'geometri':185 'gin':169,182,256,268,432,558,656,1796,1862 'gist':184,197,1797 'github.com':1745,1934,1938 'github.com/cofin/flow/blob/main/templates/styleguides/databases/postgres_psql.md)':1937 'github.com/cofin/flow/blob/main/templates/styleguides/general.md)':1933 'github.com/gemini-cli-extensions/postgresql':1744 'global':1328,1470 'guardrail':501 'guid':1762 'ha':1550,1576,1598,1889 'handl':1830 'held':1676,1687 'high':342,1044,1333,1338 'high-churn':1332,1337 'higher':1563 'highest':1682 'hit':602,986,996,1000,1008 'host':74,1606 'hot':1507 'i/o':1475 'id':113,139,144,231,279,719,794 'identifi':594 'idl':1243,1656 'idx':163,178,193,208,225,262,752,1059,1068,1186,1188,1191 'ii':1537,1542 'impact':820,1476 'import':12 'improv':527 'incompat':1717 'increas':339 'index':18,147,162,177,192,207,215,216,224,257,261,325,327,347,351,354,412,419,426,429,433,440,480,519,520,537,559,611,636,642,657,686,748,750,772,1165,1184,1198,1759,1788,1791,1800,1802,1863 'indexrelid':1182,1204 'indexrelnam':1175 'ini':856,1473,1603 'input':509 'inspect':1753 'instal':1743 'integr':1952 'interpol':507,632 'interv':727,802,1248 'join':713,788,1285,1785 'json':552,563 'json/jsonb':1855 'jsonb':49,170,238,270,276,366,435,550,553,653,1780,1858 'keep':1940 'key':237,385,876,1875 'language/framework':1923 'larg':200,322,491,1390 'last':1143,1145 'latenc':952 'later':1784 'least':674 'left':931,965,1010,1232,1268,1274 'level':1727 'librari':859 'like':316 'limit':428,735,810,843,946,983,1025,1097,1163,1206,1492 'listen':1613,1616 'live':1076,1089,1124,1133,1432 'load':1548 'local':679 'localhost':66 'localhost/mydb':97 'lock':1715 'log':210,1659,1662 'logic':1893 'long':1216 'long-run':1215 'low':338,1559 'lower':1374 'manag':30,1869 'matter':221 'max':101,1526,1635 'mean':824,830,900,906,957,963,979 'measur':534 'mem':336,341,469 'merg':333 'meta':1819 'meta-command':1818 'method':331 'middlewar':1599 'migrat':1898,1906 'min':98,1643 'minimum':1381 'missing/unused':324 'mode':1551,1629,1632,1668,1669,1709,1720 'monitor':593,845,1210 'ms':831,897,907,916,964,1373 'multipl':73 'mutat':299 'myapp':72 'mydb':1605,1611 'n':1075,1088,1120,1123,1128,1132,1135,1153,1159,1431 'name':71,114,140,244,281,606,1053 'natur':201 'navig':241 'nearest':189 'nearest-neighbor':188 'need':1594 'neighbor':190 'never':506,581 'node':1851 'node-postgr':1850 'nois':1399 'non':678 'non-loc':677 'normal':377 'nullif':997,1065,1131 'numer':827,893,903,912,927,960 'o':712,787 'o.created':707,724,732,782,799,807 'o.id':705,780 'o.status':721,796 'o.total':706,781 'o.user':718,793 'object':274,278 'offici':1909 'op':272,1783 'open':39,582 'open-sourc':38 'oper':561,1781,1859 'optim':28,532,687 'order':165,202,226,229,308,691,711,730,743,753,757,786,805,837,940,977,1019,1092,1157,1199,1251,1347 'outlier':953 'output':634 'overal':819 'overhead':1557 'overrid':1327,1502 'parallel':1841 'paramet':668 'parameter':391,504,628 'partial':214,353,425,518,641,746,1799 'pass':1498 'path':271,1861 'patroni':1895 'pattern':22,60,239,1775,1844,1856 'pct':930,1009,1074,1142 'pend':235,722,754,763,797 'per':988,1324,1504 'per-tabl':1323,1503 'perform':29,446,529,1634,1789,1833 'pg':456,482,588,815,834,847,860,873,877,937,971,1016,1030,1037,1079,1108,1111,1148,1168,1176,1179,1195,1201,1211,1238,1281,1286,1293,1299,1311,1316,1837,1880,1882,1885 'pg14':1486 'pg_stat_statements.max':865 'pg_stat_statements.track':863 'pgaudit':1874 'pgbouncer':496,575,665,1533,1539,1600,1612,1809 'pgbouncer.ini':1602 'pgpool':1536,1541 'pgpool-ii':1535,1540 'pgtap':1907 'pgvector':1879 'pid':1220,1263,1267,1295,1301,1307,1314,1320 'pitr':1896 'pl/pgsql':16,54,1823 'placehold':512,629 'plain':562 'plan':478,698 'pool':91,94,495,571,580,662,667,1532,1546,1547,1628,1640,1644,1648,1652,1808 'pool.acquire':106 'port':1608,1614 'postgi':1878 'postgr':1,1852 'postgresql':14,26,33,34,622,1739,1936 'postgresql.conf':10,853,1471 'predic':329,443 'prefer':403,438,517 'preload':858 'prepar':1697,1711,1722 'preserv':569 'pretti':1110,1178 'prevent':613 'primari':78,384,1543,1593 'principl':1932 'privileg':1872 'procedur':1827 'process':236,1562 'produc':13 'product':500,573,592 'psql':8,1812,1815 'psqlrc':1821 'psycopg':121,398,516,1846 'psycopg.asyncconnection.connect':127 'psycopg/asyncpg':11 'purpos':1544 'python':88 'queri':15,27,300,389,392,437,454,461,505,540,596,626,640,652,660,692,832,880,883,932,935,949,966,969,989,1011,1014,1209,1218,1222,1233,1236,1245,1258,1273,1279,1595,1750,1787,1842 'quick':57 'rais':1395 'rang':158,186 'rare':1704 'ratio':603,987 're':767 're-run':766 'read':86,1003,1023,1058,1190,1566 'read-writ':85 'readabl':402 'real':546 'recent':755 'recurs':1786 'reduc':524,1398,1460,1474,1926 'refer':58,1737,1758,1766,1772,1910 'references/admin.md':1804 'references/connections.md':1845 'references/extensions.md':1877 'references/indexing.md':1790 'references/json.md':1857 'references/migrations.md':1900 'references/performance.md':1835 'references/plpgsql.md':1825 'references/psql.md':1814 'references/queries.md':1776 'references/replication.md':1890 'references/security.md':1867 'refin':350 'relat':41,380,1113,1169,1180,1202 'releas':1700 'relev':522 'relnam':1050 'remov':344 'replic':1888,1892,1894 'replica':1575 'requir':69,675,854,1692 'reserv':1647,1651 'reset':1027,1033 'restart':855 'rewrit':539 'rls':1870 'role':1806,1868 'round':823,889,899,908,917,956,992,1061,1126 'rout':1572,1596 'row':109,219,343,523,650,1438 'rule':1924 'run':448,768,1217,1459 'rust':1853 'safe':297 'scalar':160 'scale':1351,1361,1406,1411,1429,1443,1461,1499,1511,1518,1567 'scan':320,488,741,773,1035,1046,1055,1060,1064,1067,1069,1085,1095,1187 'schema':358,615,1752,1897 'schema-chang':614 'schemanam':1049,1106,1115 'scram':1622 'scram-sha':1621 'search':53 'second':1250 'secret':65,77,96 'secur':1866 'security/roles/rls':31 'select':112,138,242,249,275,296,349,605,704,779,821,888,954,990,1029,1048,1105,1174,1219,1259,1310,1573 'semi':369 'semi-structur':368 'seq':319,740,1054,1056,1063,1066,1073,1084,1094 'sequenti':487,1034,1045 'seri':205 'server':587,1655,1674,1685 'session':83,1552,1555,1667,1684,1691,1693 'set':375,472,671,1326,1330,1348,1403 'setup':850 'sha':1623 'share':466,857,994,998,1001,1021,1915,1919 'simpl':1585 'singl':1561,1592 'size':99,102,430,525,1109,1114,1119,1170,1177,1181,1185,1203,1641,1645,1649 'skill':1930,1942 'skill-postgres' 'slow':453,690 'small':374 'sort':330 'sourc':40 'source-cofin' 'specif':1306,1947 'sql':6,47,222,240,288,693,867,881,1041,1101,1214,1336,1774 'sql/json':1860 'sqlalchemi':1849 'sqlx':1854 'ssl/tls':1873 'sslmode':68,669 'standard':48 'standbi':80 'start':414,1223,1246 'stat':457,483,548,589,816,835,848,861,874,878,938,972,1017,1028,1031,1038,1080,1149,1196,1212,1239,1282,1287,1317,1838,1883 'state':1226,1242,1694 'stateless':1680 'statement':458,590,817,836,849,862,875,879,939,973,1018,1032,1554,1698,1699,1703,1712,1723,1839,1884 'status':118,233,251,762 'stddev':909,915 'step':356,386,410,444,473,694,737,764,812 'strategi':19,413,846 'stream':1891 'string':631 'structur':370 'styleguid':1916,1920 'subqueri':409 'subset':648 'sum':922 'superus':1308 'support':45,557 'symptom':315 'tabl':323,361,378,485,492,1040,1042,1052,1082,1102,1151,1325,1335,1340,1346,1394,1401,1439,1466,1505,1508,1696 'tablenam':1107,1116 'target':82 'task':682 'temp':1695 'termin':1304,1312 'test':1908 'text':52,174,247,295,568,703,778,1421 'threshold':1379,1388,1396,1416,1426,1446 'time':204,464,598,826,841,887,892,902,911,921,925,944,959,981 'time-seri':203 'timeout':1653,1657 'timescaledb':1887 'tool':1748,1946 'tool-specif':1945 'top':460,595,882,948 'topic-agent-skills' 'topic-ai-agents' 'topic-beads' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-developer-tools' 'topic-gemini-cli' 'topic-opencode' 'topic-plugin' 'topic-slash-commands' 'topic-spec-driven-development' 'total':463,839,885,890,896,919,923,942,1112,1118 'transact':1553,1556,1630,1631,1665,1673,1679,1708,1719,1733 'tree':155,418,1795 'trgm':1886 'trigger':1341,1385,1419,1828 'trigram':175 'ts':213 'tune':447,465,1322,1472,1834 'tup':1057,1077,1090,1122,1125,1130,1134,1137,1155,1161,1189,1192,1433 'tupl':1356,1383,1415,1423,1456 'type':149,187,364,1229,1620,1792 'typic':1589 'u':285,715,790 'u.id':280,717,792 'u.name':282,709,784 'unbound':583 'update/delete':1469 'uri':62 'usag':287,637 'use':23,181,196,211,267,365,390,399,424,479,503,510,541,549,574,627,644,655,1167,1173,1579,1590,1671,1705,1729,1918 'user':116,142,230,284,484,508,714,789,1039,1081,1150,1197 'v3':122,1847 'vacuum':1342,1350,1369,1376,1378,1405,1425,1428,1458,1480,1490,1510,1810 'valid':475,618 'verbos':305 'verifi':493,624 'vip':1583 'vs':1171,1534,1666 'wait':1227,1230 'wal':1811 'watchdog':1582 'where/join/order':421 'wiki.postgresql.org':1914 'window':1778 'work':335,340,468 'worker':1523,1527 'workflow':355,1948 'write':25,87,388,528 'www.postgresql.org':1912 'www.postgresql.org/docs/current/':1911 'yes':1581 'zero':1904 'zero-downtim':1903","prices":[{"id":"11c429b7-8e8d-4897-b09e-45815f27c939","listingId":"bd3c2529-c63e-4b5e-beba-b1901cf140df","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cofin","category":"flow","install_from":"skills.sh"},"createdAt":"2026-04-23T13:04:00.712Z"}],"sources":[{"listingId":"bd3c2529-c63e-4b5e-beba-b1901cf140df","source":"github","sourceId":"cofin/flow/postgres","sourceUrl":"https://github.com/cofin/flow/tree/main/skills/postgres","isPrimary":false,"firstSeenAt":"2026-04-23T13:04:00.712Z","lastSeenAt":"2026-04-24T07:03:19.159Z"}],"details":{"listingId":"bd3c2529-c63e-4b5e-beba-b1901cf140df","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cofin","slug":"postgres","github":{"repo":"cofin/flow","stars":11,"topics":["agent-skills","ai-agents","beads","claude-code","codex","context-driven-development","cursor","developer-tools","gemini-cli","opencode","plugin","slash-commands","spec-driven-development","subagents","tdd","workflow"],"license":"apache-2.0","html_url":"https://github.com/cofin/flow","pushed_at":"2026-04-19T23:22:27Z","description":"Context-Driven Development toolkit for AI agents — spec-first planning, TDD workflow, and Beads integration.","skill_md_sha":"785a49b150d5b0045ae449fd25d2a8c94c944e3c","skill_md_path":"skills/postgres/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cofin/flow/tree/main/skills/postgres"},"layout":"multi","source":"github","category":"flow","frontmatter":{"name":"postgres","description":"Auto-activate for .sql files, psql commands, postgresql.conf, psycopg/asyncpg imports. Produces PostgreSQL queries, PL/pgSQL functions, indexing strategies, and connection patterns. Use when: writing PostgreSQL queries, optimizing performance, managing security/roles/RLS, configuring replication, writing PL/pgSQL functions/triggers, working with JSONB, using extensions, planning migrations, or connecting from application code. Not for MySQL (see mysql), AlloyDB-specific features (see alloydb), or application ORM patterns (see sqlalchemy)."},"skills_sh_url":"https://skills.sh/cofin/flow/postgres"},"updatedAt":"2026-04-24T07:03:19.159Z"}}