landsafe

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.

.github/workflows/landsafe.yml
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.

migrations/20260716_add_plan_to_users.sql

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. 1

    Install the Action

    Add ten lines of workflow YAML and Landsafe runs on every pull request that touches a migration.

  2. 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. 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
Add to GitHub

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
Get Pro

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
Get Business

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.