{"id":49148879,"url":"https://github.com/samirketema/pg_roast","last_synced_at":"2026-04-24T07:00:34.632Z","repository":{"id":352921082,"uuid":"1214135518","full_name":"samirketema/pg_roast","owner":"samirketema","description":"A Postgres extension that audits your database and harshly judges everything it finds.","archived":false,"fork":false,"pushed_at":"2026-04-21T17:11:42.000Z","size":32,"stargazers_count":20,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-23T06:03:14.940Z","etag":null,"topics":["database","extension","management","postgres","postgresql","postgresql-database","postgresql-extension"],"latest_commit_sha":null,"homepage":"https://github.com/samirketema/pg_roast/blob/main/README.md","language":"PLpgSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"postgresql","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/samirketema.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-18T06:55:09.000Z","updated_at":"2026-04-23T03:28:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/samirketema/pg_roast","commit_stats":null,"previous_names":["samirketema/pg_roast"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/samirketema/pg_roast","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samirketema%2Fpg_roast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samirketema%2Fpg_roast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samirketema%2Fpg_roast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samirketema%2Fpg_roast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/samirketema","download_url":"https://codeload.github.com/samirketema/pg_roast/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samirketema%2Fpg_roast/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32212808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T03:15:14.334Z","status":"ssl_error","status_checked_at":"2026-04-24T03:15:11.608Z","response_time":64,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","extension","management","postgres","postgresql","postgresql-database","postgresql-extension"],"created_at":"2026-04-22T05:11:57.245Z","updated_at":"2026-04-24T07:00:34.622Z","avatar_url":"https://github.com/samirketema.png","language":"PLpgSQL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pg_roast\n\nA PostgreSQL extension that automatically audits your database and harshly judges everything it finds. Inspired by the book [PostgreSQL Mistakes and How to Avoid Them](https://www.manning.com/books/postgresql-mistakes-and-how-to-avoid-them).\n\n```\nCRITICAL | nullable_majority | public.events\n  → Table public.events has 68% nullable columns. What does a valid row even look like?\n\nCRITICAL | superuser_app_connection | postgres\n  → Superuser postgres is connected from 10.0.0.5 running \"myapp\". A SQL injection is now a full database takeover.\n\nCRITICAL | fsync_off | fsync\n  → fsync is OFF. If the server crashes, you will lose committed data and may end up with a corrupt cluster.\n\nWARNING  | offset_pagination | SELECT * FROM orders ...\n  → A high-frequency query uses OFFSET for pagination. OFFSET scans from the beginning every time.\n\nWARNING  | col_float | public.orders.price\n  → Column public.orders.price is a floating-point type. If this stores money, you will have rounding errors. Use NUMERIC.\n```\n\n### How is this different from pganalyze?\n\n[pganalyze](https://pganalyze.com) is a performance monitoring tool — it watches query latency, index hit rates, autovacuum activity, and helps you tune a running system. It is great at answering \"why is this slow right now?\"\n\npg_roast is an opinionated database auditor that lives entirely inside your database. It answers a different question: \"what is wrong with this database?\" It covers schema design, naming anti-patterns, missing constraints, security misconfigurations, operational health, and query behavior — the kind of things that cause problems months later, not necessarily today.\n\nThe other practical difference: pganalyze requires an account, an agent, and your query data leaving your server. pg_roast is a single `CREATE EXTENSION` with no external dependencies.\n\n## Requirements\n\n- PostgreSQL 14+\n- C compiler and `pg_config` on `PATH`\n\n## Install\n\n```bash\ngit clone https://github.com/samirketema/pg_roast\ncd pg_roast\nmake\nmake install\n```\n\n### Configure PostgreSQL\n\npg_roast needs two things in `postgresql.conf`: to be loaded at startup, and to know which database to audit.\n\n**Find your `postgresql.conf`** by running this in psql:\n\n```sql\nSHOW config_file;\n```\n\nCommon locations:\n- **macOS (Homebrew):** `/opt/homebrew/var/postgresql@14/postgresql.conf`\n- **Linux (apt):** `/etc/postgresql/14/main/postgresql.conf`\n- **Linux (yum):** `/var/lib/pgsql/14/data/postgresql.conf`\n\nOpen it and add (or update) these lines:\n\n```\nshared_preload_libraries = 'pg_roast'   # if you already have other libraries here,\n                                         # add pg_roast to the comma-separated list\npg_roast.database = 'mydb'             # the database you want to audit\npg_roast.interval = 3600               # how often to run, in seconds (3600 = 1 hour)\n```\n\n**Restart PostgreSQL** to apply the changes:\n\n```bash\n# macOS (Homebrew)\nbrew services restart postgresql@14\n\n# Linux (systemd)\nsudo systemctl restart postgresql\n```\n\n### Create the extension\n\nConnect to the database you set in `pg_roast.database` and run:\n\n```sql\nCREATE EXTENSION pg_roast;\n```\n\n\u003e **No restart?** The background worker (automatic periodic audits) requires `shared_preload_libraries` and a restart. If you skip this, everything still works — you just trigger audits manually with `SELECT * FROM roast.run()`.\n\n## Usage\n\n```sql\n-- Run an audit\nSELECT * FROM roast.run();\n\n-- View findings from the latest run\nSELECT severity, check_name, object_name, roast\nFROM roast.latest;\n\n-- Summary by category\nSELECT * FROM roast.summary;\n\n-- Check run history\nSELECT run_id, started_at, finished_at, triggered_by, finding_count\nFROM roast.audit_runs\nORDER BY started_at DESC;\n\n-- Clean up old runs (default: keep last 5)\nSELECT roast.clear();\n```\n\n## Configuration\n\n| Parameter | Default | Reloadable | Description |\n|-----------|---------|------------|-------------|\n| `pg_roast.database` | `postgres` | No | Database the background worker audits |\n| `pg_roast.interval` | `3600` | Yes | Seconds between automatic runs (60–86400) |\n| `pg_roast.auto_audit` | `true` | Yes | Pause automatic background audits without restarting |\n\n**Reloadable** parameters can be changed without a restart — edit `postgresql.conf` then run:\n\n```sql\nSELECT pg_reload_conf();\n```\n\n`pg_roast.database` always requires a full restart because the background worker connects to it at startup.\n\n## Schema\n\nAll objects live in the `roast` schema.\n\n| Object | Description |\n|--------|-------------|\n| `roast.run()` | Run an audit manually, returns `(run_id, finding_count, duration)` |\n| `roast.clear(keep int)` | Delete old findings, keep last N runs (default 5) |\n| `roast.findings` | All findings from all runs |\n| `roast.audit_runs` | Run history |\n| `roast.latest` | Findings from the most recent run, sorted by severity |\n| `roast.summary` | Finding counts grouped by severity and category |\n\nSee [CHECKS.md](CHECKS.md) for the full list of rules.\n\n## License\n\n[PostgreSQL License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamirketema%2Fpg_roast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamirketema%2Fpg_roast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamirketema%2Fpg_roast/lists"}