Two-Way Airtable Sync with n8n
Build a bidirectional sync between Airtable and Postgres or another Airtable base using n8n — with conflict resolution.
Key takeaways
- Always use a stable external ID column, not Airtable's record ID, as your source of truth.
- Use last-write-wins with timestamp comparison for conflicts.
- Trigger on the Airtable webhook (Business plan+) instead of polling when possible.
- Mirror to a staging table first, then merge — never write live without diffing.
Airtable is great for human-facing data; Postgres is great for application data; teams often need both, in sync. n8n is the cleanest tool to wire up a two-way sync without writing custom services.
Architecture
Two workflows: Airtable → Postgres (triggered by Airtable webhook or 5-minute poll) and Postgres → Airtable (triggered by Postgres NOTIFY or row insert). Both write to a sync_log table with row ID, source, and timestamp to break loops.
Loop prevention
The hardest part of two-way sync is preventing each side from re-firing the other. Solution: when writing into either side, set a updated_by = 'sync' marker. The receiving workflow checks the marker and skips if present.
Conflict resolution
Compare last_modified_at on both sides. Newest wins. Log conflicts to a Slack channel so a human can override when needed.
Frequently asked questions
- Does Airtable charge for webhooks?
- Webhooks are available on Pro and above. Polling on the free tier works for low-frequency syncs.
- Can n8n handle Airtable attachments?
- Yes. Use the Binary Data passthrough to move files between Airtable and any storage.