Buyer’s Guide

Best Serverless Databases

Written by Govind Kumar Lohar. Reviewed for technical accuracy by Deepak Gupta and Bhaskar Suthar on · Review panel

  • databases
  • serverless
  • postgres
  • infrastructure

Independent buyer’s guide. No vendor paid to be included, ranked or described a particular way. Written for engineers, architects and the people who sign off on their tooling budget. Editorial policy.

The word serverless is doing three unrelated jobs in this category, and conflating them is how teams end up with a database that bills like a utility and behaves like a cold laptop.

The first job is billing. You pay for what you consume rather than for a provisioned instance, which is genuinely different and genuinely useful when your load is spiky or your fleet of environments is mostly idle.

The second job is elasticity. Capacity moves with load without you resizing anything. This is the part that works least often as advertised, because scaling compute up is fast and scaling storage-backed state is not.

The third job, and the one that actually changes your application code, is the connection model. A traditional database expects a small number of long-lived TCP connections holding session state. A serverless application runtime produces a large number of short-lived execution contexts that cannot hold anything. Every product in this category is, underneath, an answer to that mismatch, and the answer they picked determines what SQL features you are allowed to use.

Start from the connection model and the rest of the comparison arranges itself. Start from the pricing page and you will pick something that bills beautifully and cannot run a transaction the way your ORM expects.

Key takeaways

  • The three meanings of serverless (consumption billing, elastic capacity, connectionless access) are independent. Products deliver different subsets, so decide which one you actually need.
  • An HTTP query interface removes the connection problem by removing the session, which also removes interactive transactions, prepared statement reuse, session variables and LISTEN. That is the real trade.
  • Scale to zero is excellent for the long tail of non-production databases and wrong for anything a user waits on, because the first request after idle pays for resuming compute and warming a cold cache.
  • The serverless premium stops being worth it when your load is steady. A steady workload on a metered platform is a provisioned instance with worse cost predictability.

The Postgres wire protocol: a standard, not a product

Almost every debate in this category is really a debate about one protocol, so it is worth being precise about what it is before comparing things that speak it.

The Postgres frontend and backend protocol is a stateful, message-oriented protocol over a single TCP connection. A client connects, authenticates, and then holds that connection open while the server keeps per-connection state on the other end: the current transaction, prepared statements, session-level SET values, temporary tables, advisory locks, cursors, and any LISTEN registrations. It defines both a simple query path and an extended query path with parse, bind, describe and execute steps, which is what parameterized queries and prepared statements are built from.

What it gives you

  • Interactive transactions. BEGIN, then your application decides what to do next based on what it read, then COMMIT. The database holds the transaction open across multiple round trips because the connection is the transaction’s home.
  • Prepared statements that pay off. Parse once, bind and execute many times. The saved planning work lives on the connection.
  • Session state. SET search_path, SET statement_timeout, session-scoped advisory locks, temporary tables. All of it is scoped to the connection.
  • Server push. LISTEN and NOTIFY work because the server has somewhere to push to.
  • Enormous tooling compatibility. Every language has a mature driver, every ORM targets it, every migration tool speaks it. This is worth more than any individual feature.

What it does not do

  • It does not multiplex. One connection carries one session, so N concurrent queries need N connections.
  • It does not survive the network cheaply. Establishing a connection means a TCP handshake, a TLS handshake and an authentication exchange before the first query, which is why per-request connections are expensive.
  • It does not scale to unbounded clients. Postgres forks an operating-system process per connection with its own memory, so the ceiling is a property of the server’s memory, not a configuration preference.
  • It has no concept of a request that outlives its connection. If the connection drops, the transaction is gone.

Nobody sells you the wire protocol and nobody supports it as a product. It is the reason connection poolers exist, the reason HTTP query APIs exist, and the constraint every product below is working around. If you want the pooling side of that story in depth, it is in connection poolers for Postgres.

Cold starts: what is actually happening

“Cold start” gets used for several different delays that have different fixes, and knowing which one you are hitting is the difference between a configuration change and an architecture change.

Compute resume. The database process was suspended or torn down and has to come back. On an architecture that separates compute from storage, this means scheduling a compute node, attaching it to the storage service and starting Postgres. This is the delay people mean, and it is the one that shrinks as providers optimize.

Cold page cache. The process is running but shared_buffers is empty. Every query reads from storage rather than memory. Queries are correct and slow, and the slowness persists for as long as it takes your working set to be touched. This one does not show up in a synthetic “time to first query” test, which is exactly why it surprises people in production.

Cold plan cache. No prepared statements, no cached plans. Small, real, and worse if your schema has many partitions or your queries are complicated enough that planning is expensive.

Cold connection. TCP plus TLS plus authentication, per execution context, if you are not pooling. On a serverless runtime with no connection reuse across invocations this is paid on every request, and it dwarfs the query itself for short queries.

These compose. A request arriving at a suspended database after an idle period pays all four. A request arriving at a warm database from a reused container pays none. Benchmarks published by anyone tend to measure the second case and label it the first.

Needs first-hand data: Write a script that idles for a fixed interval, then issues one trivial query (SELECT 1) and one representative production query against a candidate, recording both timings separately. Run it at several idle intervals, from one minute up to whatever your provider’s suspend threshold is plus a margin. Plot the two curves. The gap between them is your cold cache cost, and it is the number that decides whether scale to zero is usable for that database.

The connection model: HTTP versus the wire protocol

This is the fork in the road. Every product here sits on one side of it, or offers both and makes you choose per environment.

Native wire protocol with a pooler in front. Your application uses ordinary drivers and ordinary ORMs. A pooler inside the provider’s network multiplexes many client connections onto few server connections. In transaction mode, a client holds a server connection only for the duration of a transaction, which is what makes the multiplexing ratio worthwhile and what breaks session-scoped features. You keep interactive transactions within a transaction boundary, and you lose session state that spans transactions.

HTTP query API. You send SQL in a request body and get rows back in a response. There is no connection and therefore no session. Each request is independent, which is a perfect fit for an edge runtime where outbound TCP may not even be available. The cost is structural: no interactive transaction across round trips, no LISTEN, no session variables, no reusable prepared statements. Providers offer a batch or “transaction” endpoint that runs a fixed list of statements atomically, which covers many cases and does not cover the ones where statement three depends on the result of statement two.

A driver that speaks HTTP but looks like a driver. Several vendors ship a client library that presents a familiar interface over an HTTP transport. This is a usability improvement, not a semantic one. The underlying constraints are identical, and the failure mode is that your ORM compiles a query shape the transport cannot express, at runtime, in production.

The practical rule: if your application logic requires reading a row, deciding something in application code, and then writing based on that decision inside one transaction, you need the wire protocol. If your queries are self-contained, HTTP is simpler and removes an entire class of connection incidents.

Data API versus direct, per environment. A reasonable pattern is to use the HTTP path from edge and serverless functions where connections are expensive or unavailable, and the direct wire protocol from long-lived background workers and migration jobs that need full session semantics. Just make sure your ORM configuration makes that boundary explicit rather than accidental.

Needs first-hand data: Point your existing test suite at each candidate’s HTTP query path with no other changes and record exactly which tests fail and why. Then grep your application for BEGIN outside a single statement list, SET at session scope, pg_advisory_lock, LISTEN, and CREATE TEMP. The union of those two lists is your real migration cost, and it takes an afternoon to produce.

Scale to zero and what it actually costs

Scale to zero is the most oversold and most genuinely useful feature in the category, and the two facts are compatible because it is useful somewhere other than where it is sold.

Where it wins: preview environments, pull request branches, staging databases, internal tools, per-customer sandboxes, and the twenty abandoned projects in your organization’s account. These are databases that are idle the overwhelming majority of the time and where nobody is waiting. Combine it with branching and the economics change qualitatively, not incrementally, which is the subject of database branching and preview tools.

Where it loses: anything a user waits on. A production database that suspends will resume on somebody’s request, and that person pays for compute resume plus a cold cache. You can raise the suspend threshold so it effectively never fires, at which point you are paying for an always-on instance through a metered bill, which is fine as long as you know that is what you bought.

The economics question worth asking out loud is where metered billing crosses provisioned billing for your actual duty cycle. A workload with a flat baseline and no idle period is the worst case for consumption pricing, because you pay a premium for elasticity you never use. A workload with a sharp daily peak and long quiet periods is the best case.

Needs first-hand data: Take one week of your real query log and replay it against a metered candidate and a provisioned instance of comparable capability, then compare the two invoices for the same week. Do it with the real diurnal shape rather than constant load, because the whole argument for consumption billing lives in the quiet hours and a flat synthetic load hides it entirely.

Neon

Neon homepage

Postgres with compute separated from a storage service that retains page history. Scale to zero and instant copy-on-write branching both fall out of that design. It offers both the native wire protocol through a pooler and an HTTP driver for edge runtimes, which makes it one of the few options where you do not have to pick one connection model for the whole application. It is now part of the Databricks platform, positioned as Lakebase Postgres.

Pros

  • Real Postgres, so your ORM, migrations, extensions and operational knowledge all transfer unchanged
  • Branching creates a full database in the time it takes to create a pointer, which changes what a preview environment can be
  • Both a pooled wire-protocol endpoint and an HTTP driver, selectable per environment

Cons

  • Scale to zero on a user-facing database means somebody eats the resume, so production usually runs always-on and the headline feature does not apply to it
  • The storage separation means an extra network hop on every page miss, so a cold working set is slower than a single-node instance with the same data
  • Now owned by a large data-platform vendor, so roadmap and pricing follow that platform’s strategy rather than a standalone Postgres roadmap

Best for: Teams who want Postgres semantics with per-branch environments and can keep production always-on.

Pricing: Metered on compute time and stored data, with branches billed on their delta rather than as full copies.

PlanetScale

PlanetScale homepage

A MySQL platform built on Vitess, with a branching and deploy-request workflow for schema changes that is the strongest thing in the product. Schema changes are applied as non-blocking online migrations, reviewed like code, with a revert path. Its historical serverless framing came from an HTTP-first driver and consumption pricing; the underlying architecture is a sharded MySQL cluster rather than a scale-to-zero design.

Pros

  • Schema change workflow with deploy requests and a revert path is a genuine operational advance over running migrations against a live table
  • Vitess underneath means horizontal sharding is an available path rather than a rewrite
  • HTTP driver works from edge runtimes where raw TCP is awkward

Cons

  • Vitess constrains what MySQL you can write, most visibly around foreign keys and cross-shard joins and transactions, and those constraints reach your schema design
  • It is MySQL, so if your ecosystem assumes Postgres extensions you are choosing a different database, not a different host

Best for: MySQL teams whose main pain is schema migrations on large tables and who want a reviewable, revertible workflow for them.

Pricing: Plan tiers with metered usage on storage and reads and writes rather than provisioned instance size.

Turso

Turso homepage

SQLite as a hosted service, built around the idea that a database can be small, numerous and close to the user. The defining feature is cheap database creation, which makes database-per-tenant a realistic architecture rather than an operational nightmare. Replicas can sit near your compute, with writes going to a primary.

Pros

  • Creating a database is cheap enough that one per tenant or one per user becomes a reasonable design
  • SQLite semantics mean reads are extremely cheap and the mental model is simple
  • Embedded replicas let reads happen locally in your process with a sync path to the primary

Cons

  • SQLite’s single-writer model means write throughput per database has a hard ceiling you cannot configure away
  • The ecosystem around SQLite for server workloads is thinner: fewer migration tools, weaker analytical SQL, and no extension ecosystem comparable to Postgres

Best for: Multi-tenant applications with many small, read-heavy tenants where per-tenant isolation is worth more than per-tenant write throughput.

Pricing: Metered on rows read and written plus storage, with database count as a plan dimension.

Cloudflare D1

SQLite running inside Cloudflare’s network, queried from Workers. Its reason to exist is adjacency: if your compute is already a Worker, D1 is the database that needs no connection, no pooler and no egress hop. It is deliberately scoped, and the scope is the point.

Pros

  • Zero connection management from a Worker, which eliminates the entire class of problems this article is about
  • Sits inside the same platform as your compute, storage and cache, so there is one bill and one deployment model
  • Read replication across the network is a platform concern rather than something you configure

Cons

  • SQLite single-writer limits apply, and the practical database size ceiling is much lower than a server database
  • Tightly coupled to Workers as a runtime, so it is not a database you can point an existing application at

Best for: Applications already built on Cloudflare Workers with modest, mostly-read relational data.

Pricing: Metered on rows read and written plus stored data, inside the platform’s overall plan structure.

Supabase

Supabase homepage

Managed Postgres plus an application platform, with a pooler in front and a generated REST layer that functions as an HTTP query path. It is not a scale-to-zero product in the Neon sense; what makes it relevant here is that the REST and client libraries let browser and edge code query the database without a connection, with row-level security as the authorization mechanism.

Pros

  • The generated REST API gives you a connectionless query path without writing a backend
  • Row-level security lets you push authorization into the database so a connectionless client is still safe
  • Underneath it is ordinary Postgres, so the exit path is a dump and restore

Cons

  • Authorization expressed as RLS policies is real logic living in the database, and it is the part that does not migrate with your data
  • Pooled connections mean transaction-mode limitations apply by default, and the failure surfaces as an ORM error rather than a clear message

Best for: Product teams who want Postgres reachable from client and edge code without building an API layer first.

Pricing: Tiered plans per project with metered overage on database size, egress and compute.

DynamoDB

The original serverless database and still the clearest about what it is. A managed key-value and document store with single-digit millisecond access by key, no connections in the relational sense, and capacity that genuinely scales without you resizing anything. The price is that you design your access patterns first and your data model second.

Pros

  • Genuinely elastic with no instance to size, and on-demand capacity that absorbs spikes without planning
  • Requests are HTTP with IAM authentication, so there is no connection pool and no connection storm
  • Operationally quiet in a way no relational option here matches, with no vacuum, no failover semantics to learn and no version upgrades

Cons

  • Access patterns are fixed at design time. A new query shape means a new index or a migration, and ad hoc questions are effectively not available
  • No joins and limited transactions, so relational integrity moves into your application code where it will eventually be violated

Best for: Well-understood, high-volume access patterns where the key structure is stable and the workload is operational rather than exploratory.

Pricing: Metered per read and write request unit plus stored data, with a provisioned capacity mode as an alternative meter.

CockroachDB Serverless

Distributed SQL with Postgres wire compatibility, consumption billing and multi-region capability. The architecture replicates ranges across nodes with consensus on writes, so it survives node and zone loss without the failover semantics of a primary-standby pair. That consensus is also the cost.

Pros

  • Postgres wire compatibility means existing drivers and most ORMs work without a rewrite
  • Survives node and region failure as a property of the replication design rather than through a promotion event
  • Horizontal scale for both reads and writes without an application-level sharding layer

Cons

  • Distributed consensus means write latency is bounded by round trips between replicas, and a multi-region configuration makes that geographic distance you cannot optimize away
  • Postgres compatibility is at the wire and dialect level, not the extension level, so anything depending on a Postgres extension does not come with you

Best for: Applications that genuinely need multi-region writes or survive-a-region-loss availability and can pay write latency for it.

Pricing: Metered on request units and stored data, with a provisioned tier for predictable workloads.

Aurora Serverless

Aurora with a capacity layer that scales compute up and down in response to load, plus an optional HTTP Data API. It is the option for teams whose constraint is that the database must live inside an existing AWS account with existing networking, IAM and compliance boundaries, and who want the bill to follow usage.

Pros

  • Aurora underneath, so the storage layer, replicas and failover behaviour are the mature ones
  • Scales compute without a maintenance event, which removes a class of planned downtime
  • The Data API gives a connectionless HTTP path for Lambda, avoiding connection storms from a scaling function

Cons

  • Scaling responds to observed load, so a step change in traffic is served at the old capacity until it catches up
  • Cost is genuinely hard to predict because capacity units, I/O and storage all meter separately, and a workload with no idle period can cost more than the provisioned instance it replaced

Best for: AWS-resident applications with spiky or unpredictable load that need Aurora’s durability story and cannot leave the account boundary.

Pricing: Metered on capacity units per second plus storage and I/O, with a configurable minimum and maximum capacity.

How to choose

1. Decide whether you need interactive transactions. Read a row, branch in application code, write based on the result, all inside one transaction. If yes, you need the wire protocol and an HTTP-only product is out. This single question eliminates more candidates than everything else combined.

2. Decide whether your compute can hold a TCP connection. An edge runtime often cannot. A long-lived container always can. If both exist in your architecture, prefer a product offering both access paths rather than forcing one model everywhere.

3. Look at your duty cycle before your pricing page. Flat baseline load means consumption billing is a premium for elasticity you do not use. Spiky or mostly-idle means it is a genuine saving. Be honest about which one you are.

4. Separate the production decision from the environments decision. Scale to zero and branching are transformative for the dozens of non-production databases and usually wrong for the one that serves customers. Choosing differently for each is not inconsistency, it is correct.

5. Check the SQL surface, not the wire compatibility claim. Wire compatible means your driver connects. It does not mean your extensions exist, your ON CONFLICT behaves identically, or your migration tool’s introspection queries return what it expects. Run your real migration suite before you commit.

6. Write down the exit path. Standard Postgres means logical replication out. A proprietary API or a document model means a rewrite. Price that in now, because it is the number that matters if the product’s pricing changes.

ProductData modelConnection modelPicks itself when
Postgres wire protocol (standard, not a product)RelationalStateful TCP sessionYou need interactive transactions and session state
NeonPostgresPooled wire protocol or HTTPYou want Postgres with a branch per environment
PlanetScaleMySQL on VitessWire protocol or HTTPSchema migrations on large MySQL tables are the pain
TursoSQLiteHTTP or embedded replicaDatabase per tenant with many small read-heavy tenants
Cloudflare D1SQLiteIn-platform bindingYour compute is already a Worker
SupabasePostgresPooled wire protocol or RESTYou want Postgres reachable from client code with RLS
DynamoDBKey-value and documentHTTP with IAMAccess patterns are fixed and volume is high
CockroachDB ServerlessDistributed SQLPostgres wire protocolYou genuinely need multi-region writes
Aurora ServerlessPostgres or MySQLWire protocol or Data APIYou are inside AWS with spiky load

Frequently asked questions

Is serverless actually cheaper?

Only if you are idle a meaningful fraction of the time. Consumption billing charges a premium per unit of work in exchange for charging nothing when there is no work. If your load is flat, you pay the premium and collect none of the benefit. The place it is reliably cheaper is the long tail of non-production databases, and that saving is often larger than anything you will achieve on production.

Do I still need a connection pooler with a serverless database?

If you connect over the wire protocol, yes, and the pooler is usually provided by the platform. If you connect over HTTP, the concept does not apply because there is no connection to pool. The trap is a hybrid application where some paths use HTTP and some use the wire protocol, and only the second set is counted against the connection ceiling.

What breaks when I move to an HTTP query API?

Interactive transactions spanning multiple round trips, session-scoped SET commands, session-level advisory locks, temporary tables that outlive a statement, LISTEN and NOTIFY, and prepared statement reuse. Most applications hit at most two of those, and most discover which two during a deploy rather than during planning.

Should my production database scale to zero?

Almost certainly not. Somebody pays the resume, and that somebody is a user or a health check. Set the suspend threshold high enough that it never fires in production, and reserve scale to zero for environments where nobody is waiting.

Is a serverless database the same as an edge database?

No, and the confusion is common. Serverless is about how capacity is billed and connected to. Edge is about where the data physically sits relative to the user. A database can be either, both or neither. Edge databases covers the replication and consistency side of that separately.