TL;DR. Lakebase is Neon's Postgres inside Databricks, so an agent gets its own branch of production in seconds. Governed tables sync into it and read back in under 10ms, and every write the agent makes lands in a Delta table in Unity Catalog about 15 seconds later. Branches are one-way and nothing merges back. You rehearse on the branch, decide from the rows it changed, and replay the approved change as a migration. I ran the branching half on Neon myself: ten agents, ten branches, all ten deleted.
Almost every agent running inside a company today is read-only. It searches, it summarises, it answers questions about data somebody else already wrote down, and it changes nothing.
Nobody sat in a meeting and decided this. It is what you get when the first serious question about a pilot is "what happens when it's wrong", and the honest answer is that nobody knows yet. So the write path gets taken away.
Databricks has an agent framework, and so does everybody. What caught my attention this year sits lower down: the database underneath the agent picked up two properties that used to be your job to build. You can hand an agent a copy of production for the length of a task, and every row it touches lands in a governed table without the agent knowing anything about it.
I want to walk through what that is, where it stops, and what it means for the write path.
What is a database branch?
I have written about this twice before, in Preview Environments and Agentic Workflows: Branched Environments, so I will keep it short.
A branch is a copy-on-write clone of a database. The storage engine keeps every change as a new version instead of overwriting the old one, so a new branch copies no data at all. It points at the same versions the parent points at, and starts recording its own changes from that moment.
Two things follow.
Branch creation takes seconds, and stays at seconds no matter how big the database is. A branch of a 2TB database is not slower than a branch of a 10GB one. There is nothing to copy.
And a branch costs storage proportional to what it changes. A branch that modifies 50MB inside a 500GB database costs you roughly 50MB, not 500GB. So "give every test run its own database with production-shaped data in it" stops being a budget conversation.
If you have ever maintained a shared staging database you know what this is for. It is the database where somebody else's half-finished migration is why your test failed.
What Databricks shipped
Databricks bought Neon in May 2025 for about a billion dollars. Neon was a serverless Postgres company whose whole architecture was the branching I just described. Ali Ghodsi said at the time that roughly 80% of the databases being created on Neon were created by agents, not by people.
That technology is now Lakebase. It went generally available on AWS in February 2026 and on Azure a month later. Postgres 17, pgvector in the box, up to 8TB, scale-to-zero that comes back in hundreds of milliseconds on the next query, branching and point-in-time recovery.
Two integrations are the part worth your attention.
Synced tables pull a Unity Catalog table into Postgres so an application can read governed lakehouse data with sub-10ms latency and full ACID transactions. Three modes: snapshot for a one-time copy, triggered for scheduled refreshes, continuous for streaming with a 15-second floor on the interval. They are read-only by strong recommendation, only additive schema changes survive a triggered or continuous sync, and each synced table holds up to 16 connections against an instance limit of 1,000. Plan capacity around those last two.
Change Data Feed goes the other direction, and it is the one I did not expect. Every insert, update and delete on a Lakebase table is read off the Postgres write-ahead log and written as a row into a Unity Catalog managed Delta table, batched and flushed about every 15 seconds. The destination is named lb_<table_name>_history and carries five columns you did not write: _pg_change_type, _pg_lsn, _pg_xid, _timestamp and _sort_by.
It sits behind a preview flag, it needs REPLICA IDENTITY FULL on the source table, and it does not handle partitioned tables. Read the limits before you plan around it.
Figure 1. The two integrations, end to end. Select either arrow for its limits.
The audit trail becomes a table
The values of _pg_change_type are insert, delete, update_preimage and update_postimage. So for every update your agent makes you get the row as it was and the row as it became, two separate rows in a Delta table, ordered by transaction ID and log sequence number.
Figure 2. Rows written to the change feed per statement type. Select a statement.
Think about what that replaces. If you want to know what an agent did to your data today, you have three options. You can read the agent's own trace, and trust a language model's account of its own behaviour. You can hand-roll audit tables and triggers, at the price of every schema change becoming two schema changes. Or you can turn on full statement logging and go spelunking in a text file at 2am.
The Change Data Feed version is a SQL query. Every write, before and after, in a governed table sitting in the same catalog as everything else your company governs, under the same permissions.
It is plumbing, so nobody demos it. In a regulated company "we cannot see what it did" is the objection that kills the project, and a change feed answers it in SQL.
You cannot merge the branch back
Once you have seen branch-per-agent-run, the next thought is obvious. Let the agent work on its branch, review the result, merge the good ones. Git for your database. I assumed it existed and went looking for the API.
It does not exist. From the Databricks community, the accepted answer to exactly this question:
Currently, Lakebase does not have a built-in "merge" or "promote" operation that pushes child branch changes up to the parent.
Neon's own position, from before the acquisition, is that this is deliberate. They do not support automatic merging of diverged branches because a database merge is unsafe and ambiguous. Two branches both insert a row with id 4… Git calls that a conflict and makes a human read it. A database cannot reliably tell you it happened.
So the recommended path is the boring one. You capture what you did as migration scripts and apply the same scripts to the parent with Flyway or Liquibase or Alembic. Schema, not data.
Which means a branch is not a feature branch. Nothing you accumulate inside one gets folded back in, and the only thing that comes out of it is a decision about what to do next.
Ten agents, ten branches, all thrown away
Let me make that concrete, because I have run it, on Neon and not on Lakebase.
I built a small framework called multirun that takes one task and runs it N times in parallel. Each run gets its own git worktree and its own database branch off a shared seeded parent. Same prompt, same starting schema, ten agents who cannot see each other.
From the run I wrote up: ten agents, 50 minutes and 10 seconds of wall clock, 930 turns between them, 143 files touched. A branch off the ~30MB parent was ready in 1.38 seconds.
All ten designed the same thing at the top level, a teams table with a join table and a foreign key on assets. Then they split. Five chose SET NULL when a team is deleted and five chose CASCADE. Five used a composite primary key on the membership table and five used a surrogate. Eight left the team reference nullable and two made it required with a backfill.
Ten runs cannot pin a ratio. What they establish is that the split exists at all, on a question the task file assumed had one answer.
Figure 3. Where ten identical runs landed on three schema questions. n = 10 per question.
The product of the whole exercise was the diff. I compared each branch against the parent to see what the agent had done to the data, wrote up the comparison, and deleted all ten branches. Not one was merged anywhere. It never occurred to me to try, because what I wanted out of it was a decision about SET NULL versus CASCADE.
I only noticed I had been working that way after I went looking for the merge API and found there wasn't one.
What I think this changes
If you are trying to get an agent past read-only inside a company, three steps fall out of all this.
Rehearse. The agent gets a branch, provisioned by API for the length of the task, with real production-shaped data in it. It writes whatever it wants and nothing it does can reach a customer.
Decide. You diff the branch against the parent, or you query the change feed. Either way you are looking at rows, not at the agent's summary of itself. A human approves, or a deterministic check approves, or both.
Replay. The approved change gets applied to production as its own deliberate act, by migration or through the normal application write path with the usual permissions on it. Then the branch goes away.
The agent never holds a credential that can hurt you, and the audit story is finished before anybody asks for it. Most of this is ordinary engineering with no model in it anywhere.
I have not run this on Lakebase. I have run the branching half, on Neon, on my own hardware, for about thirty-two dollars of list-price tokens, and it worked well enough that I stopped thinking of database branches as a testing trick. The rest is a workspace I have not spun up.
So if your agent is stuck at read-only, go and look at where it would write, and at how you would show somebody afterwards what it wrote.
Thank you for reading.
After-post notes
N1: multirun is open source at github.com/a2wio/multirun, and the write-up linked above has the full numbers.