Wiring a Next.js front end to Airtable: cache, mirror, or clean break
Tutorials wire a public front end straight to a no-code base's API. The setup works — until the documented 5 req/s per-base limit, pagination and attachment expiry catch up with it. Three architecture patterns answer, depending on traffic, required freshness and write direction.
TL;DR
- The Airtable API is limited to 5 requests per second per base, on every plan; beyond that, it returns a 429 status code and enforces a 30-second wait (official documentation, checked August 12, 2026).
- A public front end wired directly to the API turns every visit into API calls: the ceiling is reached by construction. That is usage outside the interface contract, not a product weakness.
- Independently of traffic, attachment URLs served by the API expire after about 2 hours: served directly, images go dead.
- Three patterns cover the need: application cache (Next.js ISR and revalidation), Postgres mirror (continuous replication, reads on the mirror), clean break (the base becomes the back office, the app lives on its own database).
- The choice turns on three measurable axes — read volume, required freshness, write direction — and no pattern dominates the other two.
- Our Airtable → Supabase → Next.js pipeline runs in production across 8 applications; the decision table below comes out of that practice (Ownward internal data, 2026).
The tutorial holds, until the arithmetic catches up
Using Airtable as the backend of a Next.js front end: the tutorial takes a few lines of code and works in a demo. Our thesis fits in one refutable sentence: the setup is correct as long as the product of traffic × pages × freshness stays under the API's documented limits — and most tutorials never run that calculation.
Let's run it. The Airtable API rate limit is 5 requests per second per base, on all plans, plus a global ceiling of 50 req/s per user across personal access tokens. Beyond that: a 429 status code, then a 30-second wait before requests succeed again.
Pagination sets the other bound: 100 records per page at most, with an offset to pass back on every call. Reading a 50,000-record table therefore takes 500 sequential requests — at 5 req/s, roughly 100 seconds per full read.
Add the monthly quotas — 1,000 calls on Free, 100,000 on Team, no monthly cap on Business and Enterprise Scale — and on Team, once the quota is spent, throughput drops to 2 req/s until the 1st of the month, a budget a public front end burns in the background.
| Documented limit (August 12, 2026) | Value |
|---|---|
| Throughput per base | 5 req/s, all plans |
| Throughput per user (tokens) | 50 req/s |
| Over the limit | 429 + 30 s wait |
| Read pagination | 100 records per page max |
| Monthly calls Free / Team | 1,000 / 100,000 |
| Team after quota | 2 req/s |
Two constraints traffic does not explain
The first hits even a site with ten visitors a day: attachment URLs obtained through the API expire after about 2 hours. Airtable recommends downloading the files and discourages using the platform as a CDN. A directly wired front end therefore breaks its images within two hours; any serious pattern re-hosts the assets.
The second is the API's own life cycle. Legacy API keys stopped working on February 1, 2024, in favor of personal access tokens and OAuth; token-created webhooks expire after 7 days without a refresh. Nothing abnormal: APIs evolve. But a directly wired front end marries its vendor's roadmap — a coupling described in the five forms of vendor lock-in.
Pattern 1 — the application cache: ISR and revalidation
The first reflex is not to replicate, but to stop turning every visit into an API call. Next.js Incremental Static Regeneration serves the cached page — even a stale one — and regenerates in the background: the stale-while-revalidate mechanism, standardized at the HTTP level by RFC 5861 back in 2010. The official docs recommend high revalidation times: "1 hour instead of 1 second".
// Airtable is only called at regeneration time,
// at most once per hour.
const res = await fetch(airtableUrl, {
headers: { Authorization: `Bearer ${token}` },
next: { revalidate: 3600, tags: ["catalog"] },
});
Two operating conditions. First, in the App Router, fetch caching is opt-in ("Caching is opt-in"): the tutorial that "worked" as a static build stops caching the moment the route turns dynamic, and every visit becomes an API call again. Second, on-demand revalidation (revalidatePath, revalidateTag) invalidates without regenerating, and the default file cache is per instance: with multiple instances, only the one receiving the call is invalidated, unless a shared cache handler is configured.
The ISR cache is the right pattern when traffic is read-heavy, freshness is tolerant — minutes to hours — and writes stay in Airtable. It solves neither joins, nor search, nor attachments.
Pattern 2 — the Postgres mirror: read somewhere other than the API
When search, joins or read volume exceed what 5 req/s and 100 records per page allow, you replicate. The conceptual frame is PostgreSQL logical replication: an initial snapshot, then a continuous stream of changes applied in order. On the Airtable side, the stream comes from webhooks: a data-less ping, with the client fetching the payloads, at-least-once delivery — and a 7-day expiry without refresh, to be handled on the infra side.
Each stage of the mirror has its documented constraint — the pipeline is sized on these four lines:
| Mirror stage | Mechanism | Documented constraint (August 12, 2026) |
|---|---|---|
| Notification | Airtable webhook (data-less ping) | At-least-once delivery; 7-day expiry without refresh |
| Fetch | Paginated API reads | 100 records per page, 5 req/s per base |
| Apply | Upsert into Postgres | Initial snapshot, then ordered change stream |
| Read | Next.js front end on the mirror | RLS policies; transaction pooler for serverless |
The Postgres mirror lives well in a managed database like Supabase: Row Level Security there is a Postgres primitive — each policy adds an implicit WHERE clause — which allows direct reads from the client. For a serverless front end, connections go through the transaction pooler (Supavisor, port 6543), designed for functions that open transient connections.
This is the pattern we industrialized: a mapping-driven synchronization engine (Python, orchestrated on Trigger.dev) connects six CRM/ERP systems — Airtable among them — to a single reference store; a new source is a new mapping, not new code. Our Airtable → Supabase → Next.js pipeline runs in production across 8 applications (Ownward internal data, 2026).
The mirror fits when reads outgrow the API but writes stay in Airtable: the base remains the source of truth, and the front end reads a copy that is fresh to within a few minutes.
Pattern 3 — the clean break: the base becomes the back office
The third pattern triggers on one precise signal: the write direction inverts. As soon as the application creates its own data — user accounts, transactions, multi-tenant records — the question is no longer "how do we read the base faster" but "who owns the model". The app then lives on its own database; the no-code base remains, if needed, the back office.
We took that path for edorma: a weekly Excel/HTML dashboard maintained by hand every Monday, turned into a multi-tenant SaaS isolated with Postgres Row Level Security (Ownward internal data, 2026).
The clean break is not a mandatory destination. In one year, we built 17 custom Airtable extensions now in production — including a full CRM (telephony, templated emails, SMS, interactive maps) — adopted immediately because the team stayed in its tool (Ownward internal data, 2026). You invest in the base when the work happens there; you offload it when the product is no longer the base. The reading grid is the same as for industrializing an automation: it is the tool's role that changes, not its value.
What doing nothing costs — A directly wired front end pays the limits at full price. At the first traffic spike, the API answers 429 and enforces a 30-second wait, visible to every visitor; images expire after about 2 hours; on the Team plan, once the 100,000-call quota is spent, everything drops to 2 req/s until the 1st of the month. None of these incidents is a bug: each one is documented, and therefore computable before going live.
The decision table
Three axes settle it: read traffic, required freshness, write direction. The first axis that overflows designates the pattern.
| Read traffic | Required freshness | Write direction | Indicated pattern |
|---|---|---|---|
| Low (brochure site, catalog) | Hours | Teams write in Airtable | Direct + ISR cache, long revalidation |
| Medium | Minutes | Teams write in Airtable | Cache + on-demand revalidation (webhook → revalidateTag) |
| High, search, joins | Minutes | Teams write in Airtable | Postgres mirror, reads on the mirror |
| High | Seconds | Teams write in Airtable | Mirror + incremental webhook stream, dynamic rendering |
| Any | Any | The app writes (accounts, transactions, multi-tenant) | Clean break: the app on its own database, the base as back office |
In every case: re-host attachments (roughly 2-hour expiry) and plan for webhook refreshes (7 days). When in doubt, start with the cache: the only one of the three that can be removed without dismantling anything.
The limits of this approach
Three axes simplify a hybrid reality: most systems combine patterns — a cache in front of a mirror, a partial break table by table. The table also ignores decisive factors: team skills, access governance, pipeline operating costs (monitoring, error recovery, webhooks to refresh). Our production numbers come from a single stack — Supabase and Vercel — while other Postgres combinations play the same role. Finally, the limits quoted are those of August 12, 2026: they evolve, and the calculation should be redone on the date of your decision.
Key takeaways
- The direct hookup has a validity domain, bounded by 5 req/s per base, 100-record pagination and attachment expiry — a domain you can compute before the first line of code.
- Cache, mirror and clean break cannot be ranked: each answers a different overflow — call frequency, read volume, write direction.
- Reversibility is asymmetric: a cache can be added and removed without touching the rest of the system, a clean break cannot be replayed backwards — one more reason to decide on the axes rather than on instinct.
A no-code base is an excellent back office, with an API that is honest about its limits; the setup decides the rest. Run the arithmetic, pick the pattern on three axes, keep the teams in their tool: that is the approach we detail in how we build. Ownward helps companies perform better through technology — and above all, take back control.
Sources
- Airtable Web API rate limits — Airtable, developer documentation, accessed August 12, 2026.
- Managing API call limits per plan — Airtable Support, accessed August 12, 2026.
- "List records" endpoint: pagination and offset — Airtable, developer documentation, accessed August 12, 2026.
- Attachment URL behavior — Airtable Support, accessed August 12, 2026.
- Webhooks overview — Airtable, developer documentation, accessed August 12, 2026.
- End of legacy API keys on February 1, 2024 — Airtable Support, accessed August 12, 2026.
- Incremental Static Regeneration guide — Vercel / Next.js, official docs v16.3.0, accessed August 12, 2026.
- fetch API reference and its opt-in cache — Vercel / Next.js, official docs v16.3.0, accessed August 12, 2026.
- PostgreSQL logical replication — PostgreSQL Global Development Group, official docs, accessed August 12, 2026.
- Row Level Security in Postgres — Supabase, official documentation, accessed August 12, 2026.
- Connecting to Postgres and the Supavisor pooler — Supabase, official documentation, accessed August 12, 2026.
- RFC 5861, HTTP Cache-Control Extensions for Stale Content — IETF / RFC Editor, May 2010 (stable standard), accessed August 12, 2026.
Ownward internal data, 2026, for the production facts stated in the first person.
Data and pricing verified on August 12, 2026.
All trademarks belong to their respective owners. This article is neither sponsored nor endorsed by the vendors mentioned.
Is this on your desk right now?
Tell us where you stand. We reply with concrete elements — what we would do first, in your business.
Keep reading
All insightsSeptember 11, 2026 · 7 min read
Govern a Base Like an Internal Product
A spreadsheet updated by hand every Monday, a base built one evening that became critical: most business tools are born without an owner or rules. As long as nobody answers for them, they are not tools that last — they are shadow IT on borrowed time.
September 1, 2026 · 6 min read
Airtable as scaffolding: build what you plan to take down
In 2025, half of IT projects run over deadline, budget or scope, and nearly one in five is abandoned. Yet every internal tool starts as if it were definitive. Owning the temporary — a no-code base built in days, designed to be taken down — remains the decision nobody dares to claim.