The databasePart 1 of 6

Why separated storage/compute Postgres is the right database for AI agents

The entity creating databases is no longer a human filling out a provisioning form — it's an agent, spinning up hundreds of short-lived, mostly-idle databases. That workload breaks the assumptions a traditional Postgres-per-app is built on. Here's why storage/compute separation with copy-on-write branching and scale-to-zero is the architecture that actually fits, mapped primitive-by-primitive to what agents do.

Why separated storage/compute Postgres is the right database for AI agents

For decades a database was provisioned by a person: you sized an instance, you waited, you paid for it whether or not it was busy, and you did it rarely and carefully. AI agents invert every part of that — especially the carefully.

An agent building an app wants its database the way it wants a file: created on the spot, iterated on in the same breath, thrown away if it's wrong. And it needs to do all of that without being careful — no human weighing whether a migration is safe, whether a backfill is reversible, whether spinning up another database is worth the cost. The whole value of an agent is that it acts; a database it has to tiptoe around is one that stalls the loop.

So the real question isn't "how do we give an agent a database." It's: how do we make database operations cheap and reversible enough that an agent can create and iterate on them freely, on the fly, and self-correct when it gets it wrong? That's an architecture question, and the answer is to stop coupling the data to a running process.

This isn't speculative. When Databricks acquired Neon in 2025, the headline number was that over 80% of databases on the platform were being created by AI agents, not humans — up from ~30% a year earlier, with agents creating thousands of databases a day. The provisioning model built for human-paced, long-lived instances is the wrong tool for that.

This post is the architectural argument: what agentic database load actually looks like, why the obvious designs fail, and how three primitives — O(1) copy-on-write branching, scale-to-zero compute, and branch-at-LSN — map cleanly onto what agents do. The companion posts cover two of those mechanisms in depth (scale-to-zero, time-travel); this one is why they're the right primitives.


The shape of agentic database load

An agent's relationship to a database has five properties a human's doesn't:

  • Numerous. One agent run can want several databases (per app, per experiment, per test). Across a platform that's thousands, created by software at machine speed.
  • Instant. The agent treats a database like a file — it expects to create one and use it in the same breath, not file a ticket and wait minutes.
  • Mostly idle. The vast majority are experiments, half-finished builds, or apps waiting for their first user. Aggregate utilization is low; the long tail is enormous.
  • Isolation-required. An agent's mistake in one app's database must not touch another's. Multi-tenant-by-filter is not enough when the tenant is an unsupervised program.
  • Mistake-prone and irreversible. Agents run migrations and UPDATEs confidently and occasionally catastrophically. The data needs an undo.

AI agent

db: app A — warm

db: app B — idle

db: experiment — idle

db: preview — idle

db: throwaway — idle

The picture to hold in your head: a fan-out of many databases, almost all of them grey.


Why the obvious designs fail

An instance per app. Correct isolation, but provisioning is slow (seconds to minutes), and every instance carries a permanent cost floor — RAM, a process, storage — whether or not anyone is connected. Multiply by the idle long tail and the bill is dominated by databases nobody is using. A non-starter at agent scale.

One big shared database, isolated by schema/RLS. Cheap and fast, but it trades away the isolation you most need: a bad migration or a runaway query in one app's schema is now a shared-blast-radius event, and "undo this app's data" means surgically untangling it from everyone else's. Acceptable when a human is in the loop; not when the actor is an autonomous agent.

The tension is real: you want instance-grade isolation at file-grade cost and speed. That's only possible if you stop coupling the database's data to a running process.


The three primitives that fit

Separate storage from compute — the data lives in a versioned page store; the Postgres process is stateless and reads pages on demand — and three primitives fall out, each answering one property of the workload:

Workload property Primitive Why it fits
Instant, numerous O(1) copy-on-write branch A new database is a metadata pointer, not a copy — sub-second regardless of size. The agent creates one like a file.
Mostly idle Scale-to-zero compute Remove the process when no one's connected; the data stays in the page store. Idle databases cost ~nothing.
Isolation, undo, experimentation Branch at an LSN Fork the exact state at a point in time, copy-on-write. Cheap isolated copies, instant rollback, parallel attempts.

1. Copy-on-write branch → instant, numerous

Creating a database is branching a timeline: the child shares the parent's unchanged pages and only writes a page when it diverges. No bytes are copied, so creation is O(1) in metadata — the same whether the parent holds a kilobyte or a hundred gigabytes. An agent can provision a fully isolated Postgres in the time it takes to write a file, and do it a thousand times without the storage bill scaling with the count.

2. Scale-to-zero → mostly idle is free

Because the data isn't tied to the process, you can delete the process. When nobody's connected, the compute scales to zero; the next connection transparently wakes it. The idle long tail — most of the fleet — costs only storage, not running instances. Cost becomes proportional to queries actually served, not databases provisioned. (How the wake is made invisible — wire-protocol parsing, single-flight wake, connection parking — is the scale-to-zero post.)

3. Branch at an LSN → isolation, undo, experimentation

The same branch primitive, pinned to a specific WAL position, is the most agent-relevant one. It gives you:

  • Reversibility. Tag a checkpoint per generation; restoring forks the state at that LSN and points the app at it — code and data roll back together. An agent's confident-but-wrong migration becomes a one-click undo. (The time-travel post is the deep dive.)
  • Safe experimentation. An agent can fork the database, try a destructive migration or a data backfill, verify it, and keep or discard the branch — without touching the real data.
  • Parallel attempts. Fork once per approach from the same seed and run them side by side; CoW means N branches don't cost N copies.

restore = fork @ LSN

seed @ LSN

branch: approach A

branch: approach B

checkpoint @ commit

rolled-back state


The payoff: an agent that doesn't have to be careful

Individually these are a cost win and a few features. Together they change what an agent is allowed to do.

Make creation O(1) and idle-free, and the agent stops rationing databases — it spins one up per app, per experiment, per preview, mid-task, with no cost or latency calculation in the way. Make every state reversible with a branch-at-LSN, and the agent stops being conservative about mutations — it can run the migration it's unsure about, backfill a table, attempt the destructive refactor, because the cost of being wrong is a discarded branch or a one-click rollback, not a data-loss incident.

That's the unlock. An agent that has to be careful about the database is an agent that either stalls (stopping to ask a human "is this safe?") or breaks something it can't undo. An agent on cheap, instant, reversible storage can do what agents are actually good at — act, observe, correct — on data exactly the way it already does on code: create on the fly, iterate in place, fork to try a second approach, roll back the one that didn't work. No tiptoeing.

It's also what makes handing the database lifecycle to an agent safe in the first place. The guarantee isn't "the agent is careful" — it's "the agent's mistakes are cheap to undo." Those are very different bets, and only the second one scales to autonomy.

How Adorable composes it

The primitives are Neon's; the composition for a multi-tenant app builder is ours:

  • One shared Neon tenant backs the whole platform — a single page store and WAL service. Branching is cheap precisely because everything shares storage.
  • A timeline per project is that project's database; per-app schemas and roles isolate apps that share a project's branch.
  • A connection proxy routes by database name (proj_{id}), scales each project's compute Deployment 0↔1, and parks connections across a wake — the scale-to-zero machinery.
  • Checkpoints + branch-at-LSN give every project code+data time-travel, recorded against the same git commits the agent produces.

Isolation lives at the timeline + role + Kubernetes-namespace layer, not at the tenant — which is what lets thousands of project databases share one storage backend cheaply while staying walled off from each other.


The cost model is the punchline

Trace the money. With instance-per-app, cost ≈ number of databases provisioned, forever. With separated storage + scale-to-zero, cost ≈ queries actually served plus a thin storage line — and copy-on-write keeps storage sublinear in the number of branches. For a fleet that is overwhelmingly idle and overwhelmingly agent-created, those are not small constant-factor differences; they're different asymptotes. It's the only model where "give every app, and every experiment, its own real database" is economically sane.

That's the whole bet, and it's why the industry is converging here: the database for AI agents isn't a smaller or faster instance — it's one where the data is decoupled from the process, so creation is instant, idle is free, and any point in history is one branch away. Which is the same thing said three ways: the agent gets to treat the database like code — create it on the fly, iterate in place, and undo without fear.

Build on the platform these posts describe.

Describe your app in plain English — Adorable writes the code, sets up the database, and ships it live.

Start building free