Serverless Postgres Explained - Scale to Zero, Drivers, Costs
Serverless Postgres is Postgres you pay for by use instead of by server: compute scales up under load and, on most offerings, down to zero when idle, while storage is billed separately. Neon and Aurora Serverless v2 are the best-known examples. The term is also used for something different: Postgres you can call from serverless functions over HTTP, without managing connections. Both ideas solve real problems, and they have real costs: cold starts, connection limits and bills that are harder to predict.
This article explains the moving parts, so you can tell which kind of "serverless" your app actually needs.
#Two meanings of "serverless Postgres"
- Serverless compute. The database's CPU and memory scale with load, and the provider bills per compute-hour. When there are no queries, compute can suspend. Examples: Neon, Aurora Serverless v2.
- Serverless access. The database may be an ordinary always-on server, but you query it from Cloudflare Workers, Vercel Edge Functions or Lambda through an HTTP or WebSocket driver and a pooler, so thousands of short-lived functions don't each open a TCP connection.
Many products do both. Keep them apart when you evaluate, because the first is about cost and the second is about connectivity.
#How scale to zero works
Traditional Postgres runs on one machine with its data on local disk. Serverless designs split it:
- Storage lives in a separate, durable layer.
- Compute (the Postgres process) attaches to that storage and can be stopped, resized or started elsewhere.
When no connection has been active for a while, the provider suspends compute. The next connection triggers a start. How long that takes is the cold start, and it varies a lot:
| Service | Idle time before suspend | Wake-up time (vendor docs) |
|---|---|---|
| Neon | 5 minutes (can't be changed on Free; paid plans can disable it) | A few hundred milliseconds |
| Aurora Serverless v2 (min 0 ACU) | Configurable, 5 minutes minimum, up to 1 day | About 15 seconds; 30 seconds or more after 24 hours paused |
Sources: Neon scale to zero, Aurora auto-pause.
Aurora's docs add details worth knowing: auto-pause requires Aurora PostgreSQL 13.15, 14.12, 15.7, 16.3 or newer, it doesn't pause while RDS Proxy or logical replication keeps connections open, and scheduled pg_cron jobs don't wake a paused instance: jobs whose time falls in a pause are skipped.
That last point generalizes. Anything that runs inside the database on a timer (cron, background workers, autovacuum) behaves differently when compute can disappear. Check before you rely on it.
#The connection problem
Postgres creates a process per connection, and each one costs memory. A server handles hundreds of connections, not tens of thousands. Serverless functions break that model: every cold function instance opens its own connection, and a traffic spike can exhaust the database.
Three fixes, usually combined:
- A connection pooler (PgBouncer or similar) in front of Postgres, in transaction mode, so many clients share few server connections.
- HTTP or WebSocket drivers that send queries over HTTPS to a proxy next to the database, which holds the real connections.
- Reusing clients across invocations where the runtime allows it.
Transaction pooling has rules: session state doesn't survive between transactions. Plain SET, LISTEN, SQL-level PREPARE, temporary tables and session advisory locks won't work as expected; use SET LOCAL inside a transaction. Prepared statements sent by drivers are supported by many modern poolers. See Postgres connection pooling explained.
#Serverless access on an always-on database
Not every app benefits from scale-to-zero. If your database is busy all day, a compute that never sleeps is what you want, and the problem left is connectivity.
StitchDB takes that approach. Each project's Postgres stays online, and it offers both pooling ports and an HTTP driver:
- Port 6543, transaction mode, for serverless functions using normal drivers; port 5432, session mode, for servers and migrations (pooling).
- The serverless driver in
stitchdb-js/sql, which sends queries over HTTPS, runs several statements in one transaction per request, and opens a WebSocket session for interactive transactions. Queries run through a pool on your project's server.
import { createSql } from 'stitchdb-js/sql'
const sql = createSql(env.STITCHDB_SQL_URL)
// one HTTPS request; values are sent as $1, $2 parameters
const orders = await sql`select id, total from orders where customer_id = ${customerId} limit 20`
// several statements in one transaction, one request
await sql.transaction([
sql`update stock set left = left - 1 where sku = ${sku}`,
sql`insert into orders (sku, buyer) values (${sku}, ${userId})`,
])The serverless SQL key runs queries as the project owner, bypassing row level security, so it belongs in server environments only. Results are capped at 8 MB per query, and the statement timeout defaults to 30 seconds (configurable to 5-60).
The trade-off: you pay a flat plan price rather than per compute-hour, so an idle database isn't free on paid plans, and servers are in the EU only. Plan sizes are on the pricing page.
#Cost model: when serverless saves money
Serverless compute saves money when the database is idle a lot. It costs more when it's busy all the time, because per-hour rates are higher than an equivalent reserved server.
A quick way to reason about it with Neon's published rates (Launch plan, $0.106 per CU-hour, as of November 2026):
- A dev database active 2 hours a day at 1 CU: about 60 CU-hours a month, roughly $6.40 of compute.
- A production database active 24/7 at 1 CU: about 730 CU-hours, roughly $77 of compute, before storage.
Compare that with flat-priced managed Postgres in the same size range. For constant workloads, flat pricing usually wins; for many small or spiky databases (previews, per-tenant databases, staging), serverless wins. Storage is billed separately on serverless plans (Neon lists $0.35 per GB-month).
#When serverless Postgres is a good fit
- Development, preview and staging databases that sit idle most of the day
- Many small databases, such as one per customer or per pull request
- Spiky workloads with long quiet periods
- Apps on edge runtimes that can't open TCP connections (here the driver matters more than scale-to-zero)
#When it isn't
- Steady production traffic, where an always-on server is cheaper and has no cold starts
- Workloads that depend on in-database schedulers or long-lived connections (
LISTEN/NOTIFY, logical replication) - Latency-sensitive endpoints where a cold start of seconds is unacceptable
#Checklist before you choose
- Measure idle time. Look at a week of query logs. If the database is idle less than a few hours a day, scale-to-zero saves little.
- Test the first request. Hit the app after the idle timeout and time it end to end, including your function's own cold start.
- List in-database timers. Cron jobs, queue workers and retention jobs need a database that is running when they fire.
- Count connections at peak. Multiply concurrent function instances by connections per instance and compare with the pooler's limits.
- Pick the driver. Edge runtimes need HTTP or WebSocket drivers; Node servers can use normal TCP drivers through a pooler.
#Branching, the other serverless feature
Separated storage makes copy-on-write branches cheap: a new database that shares unchanged pages with its parent. Neon's free plan includes 10 branches per project. Other platforms build branches from migrations instead; StitchDB's preview branches start from production's migrations and can optionally copy production data with personal data masked. Read more in Database branching for preview environments.
#FAQ
#What is serverless Postgres?
Postgres where compute scales with load and is billed by use, often scaling to zero when idle. The term is also used for Postgres you query over HTTP from serverless functions.
#Does serverless Postgres have cold starts?
Yes, when compute has scaled to zero. Neon documents a few hundred milliseconds; Aurora Serverless v2 about 15 seconds, longer after a day paused.
#Is serverless Postgres cheaper?
For idle or spiky databases, usually. For databases busy around the clock, flat-priced instances are usually cheaper.
#Can I use Postgres from Cloudflare Workers?
Yes, with an HTTP or WebSocket driver, such as Neon's serverless driver or StitchDB's stitchdb-js/sql, or through a connection proxy.
Query Postgres from the edge without managing connections: try StitchDB free.