Make Yourself at Home with Neon Local
A simpler way to create ephemeral environments with Neon and Docker.

The term ephemeral gets thrown around a lot in the database world, but what does it actually mean?
In the context of database branches, it refers to something temporary, short-lived, and not meant to persist. That might sound odd because databases are usually the most permanent part of your stack. So why go ephemeral?
Because not every environment needs to last.
What is Neon Local?
Neon Local is a proxy service that provides a local interface to your Neon cloud database. By default, it automatically creates a new database branch when your container starts and deletes it when it stops.
Key benefits:
- CI-friendly branching: Automatically creates and removes a database branch for each test run, no need to configure GitHub Actions manually.
- Local development support: Lets you use branching locally without manually managing branches or connection strings.
- Consistent connectivity: Your application connects to a local Postgres endpoint while Neon Local routes and authenticates to the correct project and branch.
Is Neon Local a local Postgres instance?
No, not quite, and for good reason. Local Postgres instances, while great in some scenarios, also come with drawbacks. They can lead to environment drift, where your local setup differs from production in subtle but painful ways. They’re also slow to restore from a dump or recreate accurately, making it harder to spin up a fresh, production-like environment for developing. And when it comes to testing, running parallel or per-branch environments is tricky, often forcing you into a shared database that’s not ideal for reliability or reproducibility.
So, Neon Local adopts a hybrid approach. With Neon’s instant branching, look how fast it is to automatically spin up and tear down a truly ephemeral, safe, cloud-based, isolated environment using Docker!
How to use Neon Local
There are several ways to use Neon Local, including using Docker compose and Docker run commands, with a variety of Postgres clients, and with configuration options to suit your needs.
To give you just one example, here are some code snippets that show how you might use Neon Local in a JavaScript application using our serverless driver and a docker-compose.yml
file.
For a more comprehensive explaination, see the following guide:
Docker Compose
In this docker-compose.yml
, the app
service is set up to depend on a db
service. The db service uses the neondatabase/neon_local Docker image and is configured with the necessary environment variables. The DRIVER
is set to serverless
to indicate that Neon’s serverless driver should be used for database connections, but it is possible to use Neon Local with any Postgres client by setting the DRIVER
value to postgres
.
services:
app:
build: .
ports:
- '${PORT}:${PORT}'
volumes:
- .:/app
- /app/node_modules
environment:
- PORT=${PORT}
- NODE_ENV=${NODE_ENV}
depends_on:
- db
db:
image: neondatabase/neon_local:latest
ports:
- '5432:5432'
environment:
NEON_API_KEY: ${NEON_API_KEY}
NEON_PROJECT_ID: ${NEON_PROJECT_ID}
DRIVER: serverless
Neon serverless driver
This snippet configures the Neon serverless driver to behave differently depending on the environment. In development, it connects to Neon Local on db:5432
and sets the fetchEndpoint
accordingly. In production, the connection is established using the DATABASE_URL
environment variable.
import { neon, neonConfig } from '@neondatabase/serverless';
if (process.env.NODE_ENV !== 'production') {
neonConfig.fetchEndpoint = 'http://db:5432/sql';
}
const connectionString =
process.env.NODE_ENV === 'production' ? process.env.DATABASE_URL : 'postgres://neon:npg@db:5432/neondb';
export const sql = neon(connectionString);
Docker run
If you’re not using Docker compose, you can still use Neon Local directly with docker run
. For example:
docker run \
--name db \
-p 5432:5432 \
-e NEON_API_KEY=<neon_api_key> \
-e NEON_PROJECT_ID=<neon_project_id> \
-e DRIVER=serverless \
neondatabase/neon_local:latest
When using docker run
instead of compose, the configuration for the serverless driver changes slightly. Since the container isn’t part of a named network, you’ll need to use localhost
instead of db
in your connection settings:
import { neon, neonConfig } from '@neondatabase/serverless';
if (process.env.NODE_ENV !== 'production') {
neonConfig.fetchEndpoint = 'http://db:5432/sql';
neonConfig.fetchEndpoint = 'http://localhost:5432/sql';
}
const connectionString =
process.env.NODE_ENV === 'production' ? process.env.DATABASE_URL : 'postgres://neon:npg@db:5432/neondb';
process.env.NODE_ENV === 'production' ? process.env.DATABASE_URL : 'postgres://neon:npg@localhost:5432/neondb';
export const sql = neon(connectionString);
Neon Local usage continued
In addition to providing connection options using different drivers, Neon Local can also be configured in the following ways:
Parent Branch ID
By default, if no PARENT_BRANCH_ID
is set, Neon Local will create a new branch from your project’s main
or production
branch. However, you may prefer to branch from elsewhere, like development, staging, or testing. By specifying a PARENT_BRANCH_ID
, you can control exactly which branch Neon Local uses as the base.
Delete Branch
By default, Neon Local creates a new branch when the container starts and deletes it when it stops. That said, there are cases where you might want to keep the branch around. To persist branches between container runs, set DELETE_BRANCH
to false
, this will prevent the branch from being deleted when the container shuts down.
For more detailed configuration information, visit the docs: Neon Local.
Future Features
By default, branches created by Neon Local are assigned random names. That’s fine for short-lived, throwaway environments, but if you plan to keep a branch around for longer, it’s more practical to give it a meaningful name. We’re working on making that possible through a configuration option in an upcoming release.
We’re also exploring support for an “offline mode”, which would allow you to dump and restore a database locally, much like working with a traditional local Postgres instance. This would give developers more flexibility if working without an active connection to Neon’s cloud infrastructure.
Wrapping up
Neon has always made working with branches easy, and with Neon Local, it’s now just as simple to do from Docker environments. Whether developing, testing, or previewing features, you can spin up clean, isolated ephemeral environments that feel local but behave like prod.
Ready to give it a try? Make yourself comfortable and head over to our docs to get started.