# Serverless Databases vs Traditional: When to Use Each

URL: https://www.devopsness.com/blog/serverless-vs-traditional-database
Author: Kiril Urbonas
Published: 2026-08-06
Updated: 2026-10-31
Categories: Cloud
Tags: Serverless, Database, Cloud, Architecture, Postgres

Summary: A practitioner's guide to choosing between serverless and provisioned databases based on cost, latency, connections, and load shape.

---
# Serverless Databases vs Traditional: When to Use Each

Use a serverless database when your load is bursty or the database is idle much of the day: dev and preview environments, MVPs, internal tools. Use a provisioned instance, ideally with a reservation, once production load is steady and high. Serverless saves money by not billing idle time, at the cost of cold starts and a higher unit rate.

> [!VERIFIED]
> Neon (Launch and Scale plans), Aurora Serverless v2 with auto-pause (Aurora PostgreSQL 16.3+), PlanetScale Postgres, against neon.com pricing and docs, the AWS Aurora pricing page and Aurora User Guide, and planetscale.com/pricing. Checked October 2026.

Pick the wrong model and you either overpay for idle capacity or get paged because a cold start blew your latency budget. The question is how your workload behaves, not which technology is newer.

## Two billing models, defined

**Traditional (provisioned):** you choose an instance size, such as an RDS Postgres instance or a self-managed box, and pay for it every hour whether it serves one query or ten thousand. You size for peak and plan capacity ahead of growth.

**Serverless:** compute scales with demand and can scale to zero when idle; you pay per compute-hour plus storage. Neon and Aurora Serverless v2 fit here. Storage is decoupled from compute, which is what makes scale-to-zero and instant branching possible, and also the source of the tradeoffs below.

Note that "serverless" branding no longer guarantees scale-to-zero. As of October 2026, PlanetScale's pricing page lists fixed monthly plans (Postgres single node from $5, HA from $15) with no free tier and no mention of scaling to zero. It is a managed database with good ergonomics, but it bills like provisioned.

## The comparison at a glance

| Option | Billing unit (Oct 2026, US East) | Scales to zero | Resume latency | Pooling built in | Best fit |
|---|---|---|---|---|---|
| Neon Launch | $0.106 per CU-hour, $0.35 per GB-month | Yes, after 5 min idle (can disable) | "A few hundred milliseconds" per Neon docs | PgBouncer, transaction mode | Dev, preview, spiky apps |
| Aurora Serverless v2 | $0.12 per ACU-hour (Standard), $0.10 per GB-month | Yes, with min 0 ACU | About 15 s, 30 s+ after 24 h paused | No (RDS Proxy blocks pause) | AWS shops with idle periods |
| PlanetScale Postgres | From $5/month fixed | No | None, always on | Optional dedicated PgBouncer | Small steady workloads |
| Provisioned RDS or self-managed | Hourly instance rate, reservable | No | None, always warm | You run PgBouncer | Steady high-throughput OLTP |

## Cost: it is all about idle time

Serverless wins when the database sits idle a lot. Provisioned wins when load is steady and high, especially with a one- or three-year reservation.

Work the math with the published Neon Launch rate. A dev database that runs 1 CU only during working hours (about 40 hours a week, roughly 173 hours a month) bills about 173 × $0.106 = **$18.34** in compute. The same 1 CU left on all month (730 hours) bills **$77.38**. Same workload, 4x difference, entirely from not paying for idle.

```
$ awk 'BEGIN { rate=0.106; printf "working hours: $%.2f\nalways on:     $%.2f\n", rate*173, rate*730 }'
working hours: $18.34
always on:     $77.38
```

Now flip it. A production OLTP database busy around the clock never pauses, so you pay the per-unit rate every hour with nothing to reclaim. On Aurora, the rate for the old 0.5 ACU floor works out to roughly $44 a month before storage, and a busy writer runs many ACUs. At that point a right-sized reserved instance is usually cheaper. Price both at your real usage curve with the AWS calculator before assuming either way.

## Cold starts are real, and vendors differ by an order of magnitude

Provisioned instances are always warm. Serverless that scales to zero pays a resume on the first connection. The vendor numbers differ a lot: Neon documents reactivation "within a few hundred milliseconds", while the Aurora User Guide says a typical resume is about 15 seconds, and 30 seconds or more if the instance was paused over 24 hours. AWS explicitly recommends client connect timeouts longer than 15 seconds and retry logic.

Turning on Aurora auto-pause is one CLI call (the minimum idle interval is 300 seconds):

```
$ aws rds modify-db-cluster --db-cluster-identifier dev-cluster \
    --serverless-v2-scaling-configuration MinCapacity=0,MaxCapacity=4,SecondsUntilAutoPause=600
```

For a background job that is noise. For a user-facing request, 15 seconds is an outage.

## Connections bite serverless app tiers

Postgres connections are expensive. A provisioned setup with long-lived app servers uses a fixed pool sized to the instance. Serverless *application* tiers (Lambda, edge functions) spin up hundreds of instances, each wanting a connection, and blow past `max_connections` fast. Route them through a pooler: on Neon, add `-pooler` to the hostname, which puts PgBouncer in transaction mode in front of Postgres and accepts up to 10,000 client connections.

```
# .env
DATABASE_URL="postgresql://app:secret@ep-cool-name-123456-pooler.us-east-2.aws.neon.tech/app?sslmode=require"
DIRECT_URL="postgresql://app:secret@ep-cool-name-123456.us-east-2.aws.neon.tech/app?sslmode=require"
```

Use the direct URL for migrations, `pg_dump` and anything session-level. Our [PgBouncer connection pooling guide](/blog/postgres-connection-pooling-pgbouncer) covers sizing.

## Errors that tell you which model is hurting

| Error text | Cause | Fix |
|---|---|---|
| `FATAL: sorry, too many clients already` | Function fan-out exhausted `max_connections` | Use the pooled endpoint, cap function concurrency |
| `FATAL: remaining connection slots are reserved for non-replication superuser connections` | Same exhaustion, last slots reserved | Same as above; find leaked connections in `pg_stat_activity` |
| `ERROR: prepared statement "s0" already exists` | SQL-level prepared statements through a transaction-mode pooler | Use protocol-level prepares or the direct URL |
| Connect timeout on first request of the morning | Aurora resuming from 0 ACU | Connect timeout above 15 s, retry three times, or raise MinCapacity |
| Aurora never pauses, bill unchanged | RDS Proxy, logical replication or an idle open session keeps it awake | Remove the blocker or accept min capacity billing |

## Where this breaks

Auto-pause has fine print. Aurora will not pause with RDS Proxy attached, with logical replication on, or while any user connection is open, so a forgotten IDE session kills your savings. Paused Aurora instances skip `pg_cron` jobs and cancel in-progress autovacuum. Neon's transaction-mode pooler breaks `LISTEN/NOTIFY`, session `SET` and advisory locks. And if your data fits on one node and your reads dominate, you may not need a database server at all; [SQLite in production](/blog/sqlite-in-production) is a legitimate third option.

## Questions people ask

### Is a serverless database cheaper than RDS?

Only when it is idle a meaningful share of the time. Serverless bills per compute-hour at a higher unit rate and saves money by charging nothing while paused. A dev database used 40 hours a week costs about a quarter of the always-on price on Neon's Launch rate. A production database busy all day never pauses, so a reserved provisioned instance usually comes out cheaper.

### How long is a serverless Postgres cold start?

It depends on the platform. As of October 2026, Neon documents resuming a suspended compute within a few hundred milliseconds. AWS documents a typical Aurora Serverless v2 resume from 0 ACU at about 15 seconds, and 30 seconds or more after more than 24 hours paused. Set client connect timeouts and retries accordingly, or keep a minimum capacity warm.

### Does Aurora Serverless v2 scale to zero?

Yes, for supported engine versions. Set the cluster's minimum capacity to 0 ACUs and choose `SecondsUntilAutoPause` between 300 and 86,400 seconds. Aurora PostgreSQL needs at least 16.3, 15.7, 14.12 or 13.15; Aurora MySQL needs 3.08.0 or later. Paused instances bill only storage. RDS Proxy, logical replication or open user sessions prevent the pause.

## The call we'd make

Default to serverless for anything with uneven or unpredictable load, and for every non-production environment. Most workloads are spikier than their owners think, and dev databases idle most of the week. Move to provisioned, with a reservation, once a production workload settles into steady high load. For latency-critical paths, stay warm: either a provisioned instance or a serverless minimum capacity above zero. When you have chosen serverless, compare the vendors in [best serverless databases](/blog/best-serverless-databases).

## Sources

- [Neon pricing](https://neon.com/pricing)
- [AWS Aurora User Guide: scaling to zero ACUs with auto-pause](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2-auto-pause.html)
- [Amazon Aurora pricing](https://aws.amazon.com/rds/aurora/pricing/)
- [Neon docs: connection pooling](https://neon.com/docs/connect/connection-pooling)

