Nobody plans to migrate from Airtable to Postgres. It starts innocently: someone in ops builds a base to track purchase orders, because the ERP takes six weeks to add a field and Airtable takes six minutes. Eighteen months later that base holds 41,000 rows, eleven views, four automations held together with hope, and a linked-record structure that three people understand and one person maintains. That person just put in for two weeks of vacation, and the whole company quietly panicked.
Airtable is a brilliant product and a terrible system of record, and the distance between those two facts is where migrations are born. If you're wondering when and how to migrate from Airtable to Postgres, the short answer is: when the base becomes load-bearing, and in phases that never stop the business. Move the schema first, run both systems in parallel with a sync script, then cut over on a quiet weekend with a rollback plan you actually tested.
How you know you've hit the ceiling
The ceiling doesn't announce itself. It leaks in through symptoms that look, at first, like user error:
- The 50k-row wobble. Views that used to open instantly start thinking about it. Sorts beach themselves. Somewhere around 50,000 records, depending on attachments and linked fields, the base develops a personality, and the personality is tired.
- Automation queuing. Your zaps and scripts start arriving late to their own jobs because API rate limits turned your real-time process into a batch process you never designed.
- Linked-record spaghetti. You need a report that joins four tables, which in Airtable means a lookup of a rollup of a lookup, and the result is a number nobody fully trusts.
- The single-point-of-failure human. One power user knows which fields are safe to edit. Their calendar is now a risk register.
If two or more of these sound familiar, you're not using Airtable wrong. You've used it so right that you outgrew it. Congratulations, it's horrible.
Why Postgres is the usual landing spot
You could migrate to another no-code tool, but that's just moving the ceiling, not removing it. Postgres is the boring, correct answer for most teams: it handles the row counts you're dreaming of without breathing hard, it speaks SQL so every reporting tool on earth can talk to it, and it costs approximately nothing until you're big enough that cost is a pleasant problem.
The important mental shift is splitting the job in two. Airtable was doing data storage and user interface in one product. Postgres only does the first. You keep or rebuild a thin interface on top, which sounds like more work and is, but it's also the moment you stop renting your own process back by the seat. This "boring database, thin custom layer" pattern shows up everywhere in a sane FDE toolkit; the FDE stack essentials make the case better than I can here, and the Postgres-for-everything argument is basically this paragraph with charts.
Phase one: schema first, or how to migrate from Airtable to Postgres without regret
Migrations fail when they start with an export. The ones that work start with a spreadsheet (yes, a spreadsheet, irony noted) listing every table, every field, every linked record, and what each one means in plain language.
Three Airtable habits need explicit translation decisions:
Linked records become foreign keys
Airtable lets you link anything to anything, including linkages nobody remembers creating. In Postgres, relationships are declared and enforced. You'll discover "links" that were really typos, duplicates, or one person's private filing system. Clean them now, while it's a sorting exercise instead of an incident.
Multi-selects become join tables
An order with three tags isn't a cell with three values; it's three rows in a tags table. Feels pedantic until the first time someone asks "how many orders had both rush and export tags?" and you answer in one query instead of one afternoon.
Attachments become object storage plus a URL column
Files don't belong in the database. They belong in cheap object storage with the database holding pointers. Airtable hid this from you, which was kind of it, but the bill for that kindness shows up at scale.
Phase two: dual-write, and don't panic
Now you build the new home while the old one keeps the lights on. The pattern that keeps everyone sane:
- Stand up Postgres and load a snapshot. One-time export, transformed into your new schema, loaded and verified. This is your baseline, not your cutover.
- Write a sync script. A small job that pulls changed records from Airtable's API and upserts them into Postgres on a schedule. Hourly is fine for almost everything; nobody's purchase order needs sub-minute replication.
- Reconcile with checksums, not vibes. Row counts per table, plus a hash of a few critical columns, compared after every sync. "Looks about right" is not a reconciliation strategy.
- Freeze schema changes in Airtable. Announce that new fields require a conversation now. This will be unpopular for about nine days, which is how long the parallel phase should last.
For very small bases, you can even prototype the new shape in a single file first; SQLite for prototypes covers that trick, and the jump from SQLite to Postgres later is mostly a connection string. Bigger bases go straight to Postgres, ideally running somewhere boring and reproducible, which is where Docker on client hardware earns its keep.
Phase three: the cutover nobody noticed
Pick a weekend. Friday evening, flip Airtable to read-only (share links become view-only, and you hide the edit permissions like car keys). Run the final sync. Verify checksums. Point the new interface at Postgres. Monday morning, the team opens a different URL and finds their data exactly where they left it, which is the entire point.
Two things make this boring instead of terrifying. First, a tested rollback: you keep Airtable intact and untouched for 30 days, so "go back" is a DNS change, not a rebuild. Second, a rehearsal: you already did the full cutover once on a copy, timed it, and wrote down the steps. If your cutover plan has a step labeled "figure it out," you don't have a plan; you have a wish.
What migration actually costs
For a mid-size base, say 30 to 60k rows across a dozen tables with a handful of automations, budget two to four engineer-weeks: one for schema and cleanup, one for sync and reconciliation tooling, one for the interface rebuild, plus buffer for the surprises that are absolutely coming. Illustrative, obviously, but it's the right zip code.
Compare that with the alternative, which isn't free; it's just invoiced in a currency nobody tracks. Rate-limit retries, the reporting that can't happen, the power user who can't take a vacation, and the incident you'll eventually have at the worst possible moment. A regional distributor I know ran the numbers after their move and found they'd been spending about $1,900 a month in lost hours keeping Airtable comfortable. The migration paid for itself before the second quarter ended.
And here's the part nobody expects: the team doesn't mourn. Within two weeks, the same people who swore they'd riot over losing their grid views are asking for new reports, because the answers arrive in seconds now instead of after lunch. Airtable got you here. Be grateful, be graceful, and move. The database is patient. It'll wait. Your rate limits won't.