Postgres migration review for pull requests
Land every change safely.
Landsafe reviews every pull request for the Postgres migration that would take production down — and hands back the zero-downtime rewrite.
name: landsafe
on: pull_request
permissions:
contents: read
pull-requests: write
jobs:
landsafe:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: landsafe-dev/action@v1
with:
license: ${{ secrets.LANDSAFE_LICENSE }} # optional — Pro
Paste a migration. Watch it get caught.
PRO Pro output shown — this is what lands in your PR.
Demo snapshot: public.users 48M rows · 6.2 GB,
public.orders 12M rows · 900 MB — impact numbers below are computed against these sizes.
How it reads your PR
-
1
Install the Action
Add ten lines of workflow YAML and Landsafe runs on every pull request that touches a migration.
-
2
It comments on dangerous PRs
Every risky statement gets a finding on the PR: the lock it takes, who it blocks, and the safe path.
-
3
Pro hands you the rewrite
With a snapshot of your real table sizes, Pro estimates the blast radius and pastes the zero-downtime rewrite into the comment.
Pricing
Free
$0
- All 28 detection rules
- PR comments on every dangerous migration
- CI check (fails on critical findings)
- Unlimited repos & developers
PRO
Pro
$79/mo
- Everything in Free
- Ready-to-paste zero-downtime rewrites
- Impact estimates against your table sizes (snapshot)
- Unlimited repos & developers — one flat price per org
- License key in one minute — offline, no phone-home
- 14-day refund, no questions
Business
$299/mo
- Everything in Pro
- Org-wide policy enforcement — repos can tighten, never loosen
- Weekly cross-repo digest
- Cross-repo dashboard — trends, audit view, merged-with-criticals log
- Unlimited repos & developers — one flat price per org
More than 100 repos, or need SSO/invoicing? Talk to us.
The question one PR comment can't answer
A comment knows about its own pull request. It can't tell you which PRs merged last week with critical findings unresolved — across every repo you own. Business sends that as a weekly digest and puts it on a dashboard with trends and an audit view. Both read the data Landsafe already wrote into your own PR comments, through your own GitHub token. There is no backend and no phone-home: our servers never see your repos.
Why these mistakes take sites down
Postgres DDL is transactional and lock-honest: an ALTER TABLE takes an
ACCESS EXCLUSIVE lock, and that lock waits in the same queue as every other query.
The outage is rarely the statement itself — it's what queues up around it, and how that scales
with a table your staging environment has never seen at size.
1 slow query
Lock queue poisoning
Your "instant" DDL waits behind one long-running query for its ACCESS EXCLUSIVE slot —
and every new SELECT queues behind your DDL. The whole table is frozen before the
migration has done any work. A lock_timeout turns that into a clean, retryable failure.
every row × every index
Table rewrite math
Changing a column type — or adding one with a volatile default — makes Postgres rewrite the entire
heap and rebuild every index on it, all under ACCESS EXCLUSIVE. No reads, no writes,
for as long as that takes on your biggest table.
10k rows ≠ 48M rows
Passes in staging, fails in prod
The same statement is instant on a staging table and minutes-long on the production one, because scan and rewrite time grow with the data. Only your real table sizes can tell you what a migration costs — which is exactly what the Pro snapshot feeds the analysis.
FAQ
Which databases are supported?
Postgres only in v1, and we say so plainly: the rules encode Postgres lock semantics and version behavior (11–16), not generic SQL patterns. Depth over breadth.
Does Landsafe touch my database?
Never. Landsafe is advisory-only: it reads the SQL files in your pull request, comments, and sets a CI check. It holds no database credentials, executes nothing, and a human always merges.
What's in the snapshot Pro uses?
Table names and size statistics — estimated row counts, heap bytes, index bytes — collected once by
landsafe snapshot from the Postgres catalogs and committed as a small JSON file.
It never contains rows, values, or query text.
What can the digest and dashboard see?
Only what is already in your pull request comments. Landsafe embeds the findings it posts in the comment body, and the digest and dashboard read those comments back with your own GitHub token — the same data your team can already see on the PR. Nothing is sent to us, nothing is stored by us, and neither one ever reads your code or your database.
How does licensing work?
Offline. Your Pro license is an Ed25519-signed key you drop into the LANDSAFE_LICENSE
secret; the Action verifies the signature locally. No license server, no phone-home, CI keeps working
when we don't.
MySQL? SQL Server?
Later, possibly — MySQL first if demand holds. But every rule ships with real lock and version semantics for its engine, so each database is a deliberate project, not a regex port.
How is this different from a plain SQL linter?
A linter flags a pattern. Landsafe tells you the lock the statement takes, who it blocks, roughly how long it holds against your actual table sizes — and then hands you the ready-to-paste zero-downtime rewrite. Impact and the fix, not just a flag.