Comparison
pgrubic vs pgfence
An honest comparison of two Postgres migration linters: pgrubic (Python, 100+ rules, --fix auto-patching, built-in formatter) and pgfence (TypeScript, multi-ORM, lock modes, safe rewrites, trace mode).
What pgrubic is best at
pgrubic is a Python-based Postgres SQL linter with the broadest rule catalog in the space. As of v3.0.0 (September 2026) it ships 100+ rules covering style, modeling, naming, and a subset of migration-safety checks, plus a --fix flag that rewrites unsafe patterns in place and a built-in SQL formatter. If your team writes raw .sql migrations and you want a single tool that lints, auto-fixes, and formats, pgrubic is a strong fit.
Feature comparison
| Feature | pgrubic (v3.0.0) | pgfence (v0.8.0) |
|---|---|---|
| Language | Python | TypeScript (Node.js 20+) |
| License | GPL-3.0 | MIT |
| Rule count | 100+ rules (style, modeling, safety) | 40+ migration-safety checks |
| SQL parser | pglast (libpg_query bindings) | libpg_query (PostgreSQL's own parser) |
| Input: raw SQL | Yes | Yes |
| Input: TypeORM, Prisma, Knex, Kysely, Sequelize, Drizzle | No (raw SQL only) | Yes (built-in extractors) |
Auto-fix (--fix) | Yes (rewrites in place, full rule catalog) | Scoped: applies a pure single-statement allowlist in place (adds CONCURRENTLY, missing SET timeouts); --fix --split scaffolds sibling migration files for multi-step recipes (not every finding is auto-applied) |
| Built-in formatter | Yes | No |
| Explicit lock-mode per statement | Implicit in rule text | Yes (every statement labeled) |
| Safe rewrite recipes in output | Auto-applied for fixable rules | Yes (step-by-step expand or contract sequences) |
| Trace mode (live lock verification) | No | Yes (Docker, observes pg_locks) |
| DB-size-aware risk scoring | No | Yes (stats snapshot or read replica) |
| LSP / editor integration | No | Yes (LSP: diagnostics, hover, quick fixes) |
| VS Code extension | No (CLI only) | Yes (flvmnt.pgfence) |
| GitHub Action | Community examples | Yes (composite action) |
| Output formats | tty, Markdown lint report | tty, JSON, GitHub PR comment, GitLab Code Quality, SARIF |
| Coverage line (analyzed vs unanalyzable) | No | Yes (Trust Contract) |
| Policy checks (lock_timeout, statement_timeout, tx) | No | Yes (full policy suite) |
| Startup time | Fast (Python CLI) | Node.js startup (slower cold start) |
Where pgfence is honestly stronger
- ORM migration files. pgrubic reads raw SQL only. If your migrations live in
queryRunner.query()calls (TypeORM), Knex.raw(), SequelizeQueryInterface, Drizzle, or Prisma's generatedmigration.sql, pgfence extracts and analyzes them directly. With pgrubic you have to pipe an external tool's SQL dump. - Trust Contract. pgfence reports a coverage line on every run and surfaces UNKNOWN statements with line numbers when it cannot statically analyze dynamic SQL. pgrubic silently passes input it cannot fully resolve. The difference matters when reviewers need to know what the analyzer could not prove safe.
- LSP server and VS Code extension. pgfence ships an LSP with diagnostics, lock-mode hover cards, and code-action quick fixes, plus a VS Code extension (
flvmnt.pgfence). pgrubic is CLI only today. - Adoption signal. pgfence's rule catalog has been referenced by the postgres-language-server project (5,100+ stars). pgrubic has a smaller adoption footprint despite the larger rule count.
- Lock-mode focused output. Every pgfence finding maps the statement to its specific Postgres lock mode and the operations that lock blocks. pgrubic's broader catalog mixes style and safety, which is useful for SQL hygiene but less direct for migration review.
Where pgrubic is honestly stronger
- Rule breadth. 100+ rules vs pgfence's 40+ migration-safety checks. pgrubic covers style, modeling (naming conventions, column ordering), and general SQL hygiene that pgfence intentionally leaves out.
--fixauto-rewrites. pgrubic applies fixable rules in place across its full rule catalog. pgfence's--fixcovers a smaller allowlist of pure single-statement rules (addingCONCURRENTLY, missingSET lock_timeout), plus a--fix --splitmode that scaffolds sibling migration files for multi-step expand/contract recipes likeADD COLUMN NOT NULLorADD FOREIGN KEY. It does not auto-rewrite everything the way pgrubic does, and it never touches a multi-step recipe in place, it only scaffolds new files for you to review.- Built-in formatter. pgrubic formats SQL files alongside linting. pgfence does no formatting.
- Faster CLI startup. Python cold starts faster than Node.js. On a small migration directory the gap is real, though usually a second or two in CI.
When to choose pgrubic over pgfence
Pick pgrubic if any of these apply:
- You write raw SQL migrations exclusively and do not need ORM extraction.
- You want a single tool that lints, auto-fixes, and formats SQL.
- You value rule breadth (style + modeling + safety) over deep lock-mode coverage.
- Your team prefers Python tooling and a Python CI image.
- You already run pgrubic and want to keep it. Running pgfence alongside, for the ORM extractors and the Trust Contract coverage line, is the common pattern.
See also
- Squawk vs pgfence: the Rust option with a polished GitLab Code Quality workflow.
- Eugene vs pgfence: the other Rust option, focused on live lock tracing.
- strong_migrations vs pgfence: the Ruby/Rails original, runtime interception.
- Atlas vs pgfence: a different category. Schema-as-code migration platform with a policy engine.