Airtable to Supabase sync (new rows, updates, backfill) — a practical migration plan
A practical Airtable to Supabase sync plan for new rows, updates, and backfill, using stable record IDs, unique constraints, and UPSERT to prevent duplicates.
An Airtable to Supabase sync sounds straightforward — until you run it twice and end up with duplicate rows. Airtable “just works” because it mixes storage, UI, and computed logic. Supabase is Postgres + APIs — you get more control, but you have to make data integrity explicit.
Photo by Woliul Hasan on Unsplash
Common failure modes:
Row duplication when a sync runs twice or retries after a timeout
Broken relations (linked records) when you don’t have stable IDs
“Computed” Airtable fields (rollups/lookups/formulas) getting treated like source-of-truth columns
Do not backfill first. Backfill after new + update pipelines are stable.
Implementation checklist:
Freeze schema changes during backfill
Backfill table-by-table (or in dependency order)
Batch writes (e.g., 500–5,000 rows at a time) to avoid timeouts
Verify counts + spot-check records
Re-run backfill safely (UPSERT makes this possible)
Duplication prevention patterns that actually work
1) Use Airtable’s record ID as the durable key
Store it and enforce uniqueness:
airtable_record_id is your source-of-truth key
Every write uses it to decide “insert vs update”
2) Use database-level uniqueness + UPSERT
In Postgres terms, you want INSERT ... ON CONFLICT ... DO UPDATE.
In Supabase client terms, you want .upsert(..., { onConflict: 'airtable_record_id' })and a unique constraint in the table.
3) Treat retries as normal
Zapier retries. Scripts crash. Webhooks duplicate. Assume it’ll happen and design for it.
When to migrate computed fields (rollups/lookups/formulas)
Airtable computed fields are derived, not raw truth.
Do this after the raw pipeline is stable:
Recreate formulas as SQL views
Recreate rollups with SQL aggregations + views/materialized views
Recreate lookups via joins
A practical checkpoint:
If “new rows” + “updates” have run cleanly for 7–14 days with no duplication incidents → start Phase 2 for computed fields.
Zapier vs Script: which should you pick?
Pick Zapier when:
You need it working this week
Volumes are low to moderate
You can tolerate occasional delay/retry behavior
Pick a script/worker when:
You need strong observability + replay
You have high volume or many tables
You need custom logic (transformations, denormalization, ordering)
Many teams do both:
1) Start with Zapier for speed
2) Replace with scripts once the schema stabilizes
Suggested implementation order (fastest path to “not broken”)
Raw tables + constraints in Supabase
New rows sync (ship it)
Updates sync (stabilize it)
Historical backfill (migrate old data)
Relations cleanup + normalization
Computed fields via SQL (views/rollups)
Get help building this
An Airtable to Supabase sync usually breaks at the same two points: the first time a webhook retries and creates a duplicate, and when backfill runs against a schema that wasn’t built for it. If you’ve hit that wall, book a ZoomFlow session — one of our consultants can walk through your schema, set up the UPSERT constraints, and get your sync running cleanly in a single call.
A small fabric manufacturer lost inventory to handwritten label corrections. Connex fixed their Zapier stack, migrated ownership, and automated notifications — saving ~$17k/yr.
JobPro Sage integration without a public API is doable. Use outbound webhooks and a middleware layer to sync customers, jobs, invoices, and job costs reliably.