The best Vercel Postgres alternatives in 2026
Vercel Postgres was a convenience product. It gave you a Postgres connection string from inside the dashboard you were already in, on the bill you were already paying, with environment variables wired up automatically. Underneath, it was Neon. Vercel has since moved storage products onto the marketplace model, so the database you provision from Vercel is now explicitly the provider's — Neon, or one of the others listed there — rather than a Vercel-branded layer.
That is a reasonable outcome, but it does mean a lot of people are looking at their database as a decision again rather than a default. This guide is about how to make that decision on the properties that are expensive to change later, rather than on the ones that show up in a comparison table.
What you were actually buying
Three things, and they are worth separating because different alternatives replace different ones.
- Zero-configuration wiring. The database appeared as environment variables in every environment, including preview deployments, with no manual step. This is the part people miss most.
- One bill. Storage and compute on the same invoice as hosting, drawn from the same plan.
- Serverless-shaped connectivity. A connection pooler and an HTTP driver, because a function platform opening a fresh TCP connection per invocation exhausts Postgres connection slots very quickly.
Only the third is technically load-bearing, and it stops being load-bearing the moment your application is a long-running server rather than a pile of functions. That is the fork in the road, and it determines which of the options below is right.
The connection problem, stated properly
Postgres allocates a backend process per connection, and max_connections is a small number by default — often around a hundred. A long-running server opens a pool of ten and reuses it for millions of requests, which is entirely fine. A function platform can have hundreds of concurrent instances, each opening its own connection, and the database refuses new ones long before you notice any CPU load.
There are three real answers, and picking one is more important than picking a vendor.
- Put a pooler in front. PgBouncer in transaction mode, or the provider's hosted equivalent, multiplexes thousands of client connections onto a handful of server ones. The cost is that session-scoped features stop working: prepared statements need care, LISTEN/NOTIFY does not survive, and advisory locks held across statements are unreliable.
- Use an HTTP driver. Several providers offer a driver that speaks HTTP to a stateless proxy, which removes the connection question entirely for simple queries. The cost is that you are not speaking the Postgres wire protocol, so transactions and streaming behave differently, and you are more tightly coupled to that provider.
- Stop using functions for database work. A long-running server with a normal pool has no connection problem at all, and this is the option most people forget is available.
The alternatives
- Neon — The incumbent, since it was already underneath. Genuinely good at branching: a database branch per pull request is copy-on-write and fast, which is the feature most worth keeping. Scale-to-zero on idle. Stay here if branching is central to how you work.
- Supabase — Postgres plus auth, storage, realtime, and generated APIs. The right answer if you want those things; a lot of surface area you did not ask for if you only wanted a database. Note that it is a full Postgres with extensions, not a restricted subset.
- PlanetScale — Now offering Postgres alongside its MySQL heritage, with a strong operational story around schema changes. Worth a look if online schema migration at scale is your actual pain.
- Amazon RDS or Aurora — The boring institutional answer. Maximum control, maximum knobs, and an operational burden you should only accept if someone owns it. Aurora Serverless v2 addresses idle cost but not the connection problem, which is why RDS Proxy exists.
- Crunchy Bridge — Postgres run by people who are unusually serious about Postgres. Fewer product features, more depth on the database itself. Good for teams that will use those depths.
- Digital Ocean or Render managed Postgres — Straightforward, priced predictably, sitting next to your app on the same platform. Nothing clever, which is often the correct amount of clever.
- Self-hosted Postgres — Cheapest at scale and the most work. Reasonable if you already run infrastructure and have a real backup and failover practice. Unreasonable as a cost-saving measure on a team without one.
- PandaStack — Each database is its own Firecracker microVM with a durable volume, not a schema inside a shared cluster, so a noisy neighbour is a different machine rather than a different row. Point-in-time recovery and backups are included, branching is a copy-on-write clone into a new database, and idle databases auto-suspend and wake on connect. Billing is metered on active CPU and working-set memory plus storage. Best when you want per-tenant or per-branch database isolation without operating it; less compelling if you specifically want an HTTP driver for edge functions.
Branching is the feature worth protecting
The habit Vercel Postgres users most often have and least often want to lose is a database per preview deployment. A pull request gets its own copy of the schema and data, migrations run against it, the preview app talks to it, and it disappears when the branch merges.
This is worth protecting because it changes what you can test. Migrations get tried on real data before they touch production. Reviewers click through a preview with representative content. Nobody shares a staging database and nobody blocks anyone else. If you are choosing a replacement, check that whatever you pick makes an ephemeral copy cheap — whether it is called a branch, a clone, or a fork matters less than whether it takes seconds and costs almost nothing.
# Shape of a per-PR database, whichever provider you use:
# 1. clone/branch from production (copy-on-write, seconds, not a dump)
# 2. run migrations against the copy
# 3. hand the preview deploy its connection string
# 4. destroy it when the branch merges
# On PandaStack that clone is a new database id from the source's archive:
pandastack db clone <source-db-id> --label "pr-482"
pandastack db connection <new-db-id>
# The source is untouched, so cloning production for a test is not a
# risk decision -- which is the point of doing it per pull request.Pick by situation
- Next.js app on Vercel with functions, moderate traffic → Neon or Supabase, with the pooled connection string and a driver that suits your ORM. The path of least resistance is fine here.
- You moved the app to a long-running server → any managed Postgres with a normal connection pool. The connection problem is gone; choose on backups, isolation, and price.
- Branch-per-pull-request is core to your workflow → Neon or PandaStack. Verify the clone is copy-on-write, not a restore from dump.
- Per-customer database isolation → per-tenant instances rather than per-tenant schemas. PandaStack or self-hosted; a shared cluster with row-level security is a different trade-off with different failure modes.
- You need auth, storage, and realtime as well → Supabase, and treat it as a platform decision rather than a database one.
- Regulated, on your own cloud account → RDS or Aurora, with someone named as the owner of backups and failover drills.
The short version
The question that decides this is not which vendor. It is whether your application is functions or a server, because that determines whether the connection story matters at all. Answer that first and half the list disappears.
After that, choose on the two things you cannot bolt on later: how cheap it is to make a throwaway copy of the database, and what happens the day you need to restore to a specific minute. Everything else — dashboards, drivers, regions — you can live with or work around.
Frequently asked questions
Do I have to migrate off Vercel Postgres?
Not urgently, and in most cases not at all in the sense of moving data. Vercel's storage products moved to a marketplace model where the provider is named explicitly rather than white-labelled, which for Postgres users generally means the database is now a Neon database you access directly rather than a Vercel-branded one. The connection string still works, the data is the same data, and the practical change is which dashboard you use and how it appears on your bill. What that transition does usefully create is a moment to ask whether the default is still the right choice, particularly if your workload has shifted from functions to a long-running server since you first provisioned it — that shift removes the main reason serverless-oriented Postgres existed for you. Treat it as a review, not an evacuation.
What is the difference between a pooled and a direct Postgres connection string?
A direct connection string opens a TCP connection straight to Postgres, which allocates a backend process for it and holds it for the session. That is what you want for migrations, for anything using LISTEN/NOTIFY, for session-level advisory locks, and for long transactions. A pooled string points at a connection pooler — usually PgBouncer in transaction mode — that multiplexes many client connections onto a small number of real ones, which is what makes hundreds of concurrent function instances possible without exhausting max_connections. The cost is that session state does not survive between statements: prepared statements need explicit handling, notifications do not arrive, and anything assuming the same backend across statements breaks in ways that are intermittent rather than obvious. Most providers give you both strings, and most ORMs want the pooled one for queries and the direct one for migrations.
Is database branching just a snapshot restore?
No, and the difference is what makes it usable per pull request. A snapshot restore copies the data: the time and cost scale with database size, so branching a large production database takes minutes and consumes another full copy of storage, which nobody does forty times a day. Copy-on-write branching creates a new database that initially shares its pages with the source and only allocates storage for what changes, so creation is close to instant regardless of size and the storage cost is proportional to the diff. That is the property that turns branching from an occasional operation into a routine one you can attach to every pull request. When comparing providers, the useful question is not whether they call it branching but whether creating one on a hundred-gigabyte database takes seconds or minutes.
Can I run Postgres on the same platform as my app?
Yes, and it is often the better arrangement. Co-locating the database with the application removes a network hop from every query, which matters more than people expect for chatty ORMs that issue several round trips per request, and it removes cross-provider egress from the bill. It also collapses the operational surface: one dashboard, one set of credentials, one place where preview environments get both an app and a database. The reasons to keep them separate are real but specific — you want a provider whose only job is Postgres, you have compliance requirements about where data lives, or you want the database to outlive any decision about the app platform. If none of those apply, same-platform is a simplification rather than a compromise.
How do I move a Postgres database between providers with minimal downtime?
For most applications the honest answer is a short maintenance window, because it is far simpler and the window is smaller than people fear. Take pg_dump against the source, restore into the target, verify row counts and a few known queries, then repoint the application. For a database in the low tens of gigabytes that is often under an hour, and doing it at a quiet time costs less than the engineering to avoid it. When you genuinely cannot take downtime, the tool is logical replication: create a publication on the source, subscribe from the target, let it catch up while both run, then cut over once replication lag is near zero and stop writes for a few seconds. Test the whole sequence on a clone first, and check extension availability and version compatibility on the target before you start, since those are what actually derail these migrations.
Keep reading
49ms p50 cold start. Fork, snapshot, and scale to zero.