Engineering

The record someone deleted last Tuesday

Someone deleted a record last Tuesday. You want to know who did it and what the row held before it went. On Airtable that answer exists if the deletion falls inside your plan's retention window, and you can read it on screen, but you cannot take it out of the product. On Postgres the same question is a table you wrote, and you query it the way you query anything else. The difference stays invisible until the day someone outside your team asks for the log.

What Airtable keeps, and for how long

There are two trash windows and they are not the same thing. Base trash holds deleted records, fields, tables and views for 7 days. Workspace trash holds deleted bases for 30 days, and only an Enterprise Scale admin can stretch that to 60, 90 or 180 through a retention policy. Both sit apart from revision history, which is the per-record feed showing who changed which cell.

Revision history retention is a plan attribute. Free gives you 2 weeks. Team, at $20 per seat per month billed annually or $24 monthly, gives you a year. Business, at $45 and $54, gives you two years. Enterprise Scale gives you three. The feed itself is good. It names the user, and when an automation made the edit it names that automation and links through to the run responsible.

I like that feed. Most teams writing their own backend in year one never get around to attributing a change to a specific background job, and Airtable ships it in the box. That is a real reason to be there, and it is the reason the gap below takes people by surprise.

The history that cannot leave

Airtable's own documentation is unusually direct about this. Revision history is view-only. The product has no download option, the Web API has no endpoint that returns it, and eDiscovery exports do not include it. The cell history endpoints in the API create and list redactions, so they hand nothing back.

Snapshots do not carry it either. Restoring a snapshot builds a new base rather than rolling back the one you have, and the new base arrives with record comments but no revision history. Clearing a base's history takes effect immediately and cannot be undone. There is also a gap inside the feed: changes arriving through a sync are hidden on purpose, so a synced field can hold a value the history will not explain.

None of this costs you anything on an ordinary Tuesday. It costs you on the day a customer disputes what they agreed to, or the day you leave the platform and want to carry years of edits across with you. That is when teams discover the history was never theirs to move.

When the change log is a table you wrote

On Postgres, who changed what is a schema decision. The generic audit trigger published on the PostgreSQL wiki writes a row for every insert, update, delete and truncate on a watched table. Each row carries the session user, the client IP and port, the transaction and statement and wall clock timestamps, the statement that caused the change, the row as it stood before, and the fields an update actually touched. It cannot see reads and it cannot see DDL like ALTER TABLE, which you should know before promising anyone a complete record.

Retention stops being a tier you buy. The log is a table, so it lives as long as you decide it lives, and you query it in SQL, join it against the records it describes, and hand a CSV to whoever asked. The wiki makes one sharp point about trust that is easy to skip: the application role must not own the audited tables and must not connect as a superuser, or your app can quietly rewrite its own history.

Backups are a separate question and the two get conflated constantly. Supabase keeps 7 days of daily backups on Pro at $25 a month, 14 days on Team at $599, and up to 30 on Enterprise. Point in time recovery is a priced add-on: roughly $100 a month for a 7 day window, $200 for 14, $400 for 28, and switching it on replaces the daily backups rather than adding to them. A backup answers put the database back the way it was at 15:00 on Tuesday. An audit table answers who edited this row and what did it say. You want both, and only one of them is yours to design.

When we moved Stay World Class off Webflow and Xano onto Next.js, NestJS and Supabase, the piece that made the history usable afterwards was the dullest part of the job: a four stage ETL that carried every legacy record ID across and mapped it onto a PostgreSQL UUID. Old references still resolve. A change log is worth nothing if the IDs inside it point at a system you have already switched off.

When staying put is the right answer

If your disputes surface within weeks and the log never leaves the team, Airtable already covers you, and it covers you with zero maintenance. A team on the Team plan with a one year window and an internal audience is missing nothing. Building a Postgres audit trail to replace that is work you chose for no return.

An audit table you own comes with a bill. It grows faster than the table it watches, it needs indexes and a retention policy somebody has to write, and it needs the permissions discipline above or it is theatre. Budget for a person who cares about it, because an audit log nobody maintains is worse than none: you will trust it when you should not.

The moment to move is narrow and easy to recognise. You need the history outside the product, or you need a retention window longer than your plan sells. Until one of those is true, the feed inside the expanded record is a perfectly sensible place for your change log to live.

Sources

Is your platform outgrowing its stack?

Book a call and we'll walk through how we'd approach your platform, with an estimate grounded in a working prototype.