Connect Airtable to PostgreSQL

Read records from a base, or push results back into one. Upsert on a key field so scheduled runs update existing records instead of duplicating them — the safe way to keep an operational base in sync.

What you can pull from Airtable

A Airtable job pulls records into a flat table on your schedule. Nested fields are flattened into ordinary columns, so what lands in PostgreSQL is ready to sort, filter and total rather than needing another cleanup step.

  • Any base and table
  • Views and filters
  • Append or upsert on a key

Options you can set

view
View name or ID; applies that view's own filter and sort server-side
filter_by_formula
Airtable formula, e.g. {Status}='Active'. Up to 1,000 characters
fields
Restrict the read to these field names
max_records
Stop after this many records

How it lands in PostgreSQL

PostgreSQL accepts append, replace, upsert writes. Upsert is the one that matters on a schedule: it merges on a key you choose, so matching rows are updated in place and only genuinely new records are created. Append instead, and a daily job multiplies your data.

Upsert uses key_columns as the conflict target.

  • Rows are written in chunks of 1,000 by default, configurable up to 50,000.
  • Replace truncates the target table before writing.

Authentication

You connect Airtable once through OAuth and the credential is stored server-side, never pasted into a cell or a formula. Only the scopes the connector actually calls are requested — the table below lists each one and what it is for.

What Airtable is asked for

data.records:read
Read records from the table you choose
data.records:write
Create and update records when Airtable is the destination
schema.bases:read
Populate the base/table pickers and the upsert key-field list
user.email:read
Label the connection so it is identifiable

Keeping runs incremental

Yes. Narrow server-side with a view or a filter formula so a run fetches only what changed, rather than filtering after the fact.

Pair a narrowed read with an upsert write and a re-run costs almost nothing: the rows it already knows are updated, and nothing is duplicated. That combination is what makes a frequent schedule affordable.

Common gotchas

Most of what goes wrong with a scheduled sync is not a bug — it is a detail of how one side behaves that nobody wrote down. These are the ones that come up for this pair.

Do not key an upsert on email

People change their email address. When they do, upsert cannot match, so it creates a second record - the exact duplicate you were trying to prevent, plus a stale one. Use a stable ID from the source system.

The key field has to be written

If you restrict which columns get written and the key field is not among them, there is nothing to match on and every row is treated as new.

A row that is a fact per period needs a compound key

For a daily history, one row is one entity per day. Key on the entity alone and each day overwrites the last, leaving no history at all.

Set either table or query, never both

The config rejects both being set, and rejects neither - caught when the job is saved rather than on its first run.

Set it up in four steps

  1. 1

    Connect Airtable

    Connect your Airtable account once, then pick a base and table.

  2. 2

    Connect PostgreSQL

    Host, port, database, user and password, stored encrypted.

  3. 3

    Shape the data

    Select the columns you want, filter rows, cast types and add computed fields. Everything else is dropped before it reaches the destination.

  4. 4

    Schedule it

    Run once, or on a cron. Every run refreshes PostgreSQL with the latest Airtable data.

Do I need an add-on or extension for this?

No. The job runs server-side and writes into PostgreSQL through its API, so there is nothing installed in the destination itself. It keeps running when nobody has the file open, and a copy of the file does not need anything installed to work.

How often does the data refresh?

On whatever schedule you set with a cron expression — hourly, daily, or a specific time on specific days. Each run pulls the latest from Airtable.

Do I need to write any code?

No. You connect both sides, map the fields in a wizard and set a schedule. Computed fields accept small expressions — abs, round, min, max, len — but there is nothing to host or maintain.

How do I stop duplicate records appearing?

Use upsert rather than append, and key it on a stable identifier from the source. Append creates new records every run, so a daily job leaves seven copies of every row by the end of the week.

How fast can it write?

Airtable accepts 10 records per request, and writes are paced at 4 requests a second by default against a ceiling of 5 - roughly 2,400 records a minute. That is comfortable for thousands of rows and worth planning around for hundreds of thousands.

Can I run my own SQL rather than reading a table?

Yes. Set a query instead of a table and aggregate in the database, which is usually far cheaper than moving raw rows and aggregating downstream. One statement only - multi-statement queries are rejected.

Does it need a superuser?

No. A user with SELECT on what you are reading is enough for a source; a destination needs INSERT and, for upsert, UPDATE on the target table.

Is the Airtable connector free to use?

You can connect Airtable and start syncing on the free plan.