Building Neon Object Storage - Neon<br>Add files to your Postgres branches via Neon Object Storage, our S3-compatible object store
Discord22.8k<br>Log inSign up
Back to Blog/Product<br>Building Neon Object Storage<br>S3-compatible storage that branches with your Postgres database<br>Carlota Soto–Product Marketing Lead
Aug 06, 2026
Subscribe to our changelog<br>Receive only our latest updates. No spam, guaranteed.
Subscribe<br>Neon Object Storage is in beta
It's available to all users free of charge during beta. Deploy it and give us feedback so we can take it to GA.
We just launched Neon Object Storage, a branch-aware, S3-compatible object store built into the Neon backend. If you've used Neon branches before, you know the workflow: branch main into a child and get an isolated copy of your database in about a second. Object Storage adds files to that picture. When you create a branch, the child also inherits your buckets and objects at that point in time.
We made Object Storage branchable because that's our core operating philosophy. Neon isn't shipping a database with extras bolted on. We're building a backend for apps and agents where Postgres, files, Functions, Auth, and the AI Gateway share the same branch semantics.
Branching Postgres + files in one API call
When you create a branch, you get one branch_id that forks both your Postgres data and your Object Storage buckets:
Data + files together. The child inherits your database and your buckets/objects at that point in time.
Same workflow as Postgres branches. Create preview branches, PR environments, agent runs - files follow the same branch semantics you already use for data.
Isolated by default. Uploads and deletes on the child never touch the parent or sibling branches.
Copy-on-write. The storage bill only grows if the branch diverges, nothing gets duplicated upfront.
Disposable. The child branch can be deleted as easily as it was created, without altering the parent.
The ability to branch with your database is the central feature of Neon Object Storage, so it's worth pausing to explain the Neon branching experience a bit more.
A recap: how Postgres branches on Neon
Lakebase Postgres runs standard Postgres on the lakebase architecture, with compute and storage decoupled. Compute is where queries run, and storage is where data lives - but the storage layer is custom. It runs on copy-on-write versioned by WAL, storing Postgres pages as history so we can point at a particular page without duplicating the storage underneath.
That is what happens when a branch is created. A branch starts as a pointer into the same underlying pages as its parent. Nothing is copied at create time: parent and child read the same bytes until one of them writes. The moment a row changes, that branch writes a new page for it, but everything that hasn't changed stays shared.
In practice, what this means is:
You can create as many branches as you want without multiplying storage costs upfront
Branching a 100 TB database feels exactly the same as branching a 10 MB one; it's instant, and you only pay for compute while that branch's compute is running (it scales to zero when idle)
On the lakebase architecture
This design defines a new kind of OLTP database. Get all details on how things work..
Making files branch with your database
Neon Object Storage does not reuse exactly the same branching machinery as the database - we built a lineage-and-versioning system that works together with it:
When you create a Neon branch, both systems branch together under one shared branch_id:
Postgres branches through the pageserver's page-level copy-on-write
Object Storage forks through lineage and object versions
Each Object Storage branch keeps a lineage: an ordered record of itself, its parent, and its parent's parent, back to root. Every object write on a branch becomes a new version row, tagged with a version number
Creating an Object Storage branch is one write. The child's lineage becomes the parent's lineage with the child's entry added at the front. The objects themselves don't move.
Looking up a file walks that lineage
Deleting a file the child inherited doesn't touch the parent: the child adds a version marked deleted, and lookups on that branch return that from then on
This setup carries over the essential properties of our branching experience to files. Branching stays instant no matter how much the parent has stored, isolation is the default, and you don't pay for duplicated object storage unless the branch diverges. Compute on the branch still scales to zero when idle.
Branch databases + buckets as many times as you want. You don't pay for storage copies or idle compute
This last point on costs is worth emphasizing. Because Lakebase Postgres branching is copy-on-write, creating a branch does not duplicate your database storage - and the same is now true for your Object Storage buckets. You (or your agent) can automatically create a Neon branch for every session, PR,...