Serverless databases scale to zero cost when idle and auto-scale with traffic. Three leading options target different use cases. Compare their architectures, pricing, and ideal workloads.
Architecture
Turso: Built on libSQL (a fork of SQLite). Databases are embedded and replicated to edge locations globally. Extremely low latency reads from the nearest replica.
PlanetScale: Serverless MySQL built on Vitess (the technology behind YouTube's database). Branching workflow for schema changes. MySQL-compatible.
Neon: Serverless PostgreSQL with copy-on-write branching. Separates storage and compute. Autoscales compute to zero.
Feature Comparison
| Feature | Turso | PlanetScale | Neon |
|---|---|---|---|
| Database engine | libSQL (SQLite fork) | MySQL 8.0 (Vitess) | PostgreSQL 16 |
| Branching | Yes | Yes | Yes |
| Edge replicas | Yes (global, 30+ locations) | Read replicas | Read replicas |
| Scale to zero | Yes | Yes | Yes |
| Connection pooling | Not needed (HTTP API) | Built-in | Built-in |
| Foreign keys | Yes | No (Vitess limitation) | Yes |
| Full-text search | SQLite FTS5 | MySQL full-text | PostgreSQL tsvector |
| JSON support | JSON functions | JSON columns | JSONB (advanced) |
| Extensions | Limited | N/A | Yes (pgvector, PostGIS, etc.) |
| ORM support | Drizzle, Prisma | Drizzle, Prisma | Drizzle, Prisma |
| Max database size | 8 GB (free), unlimited (paid) | Unlimited | Unlimited |
Pricing
Free Tiers
| Feature | Turso | PlanetScale | Neon |
|---|---|---|---|
| Databases | 500 | 1 | 1 project |
| Storage | 9 GB total | 5 GB | 512 MB |
| Rows read/month | 24 billion | 1 billion | N/A |
| Rows written/month | 72 million | 10 million | N/A |
| Compute | N/A | N/A | 191 compute hours |
| Edge locations | 3 | N/A | N/A |
Paid Plans
| Plan | Turso | PlanetScale | Neon |
|---|---|---|---|
| Entry/Pro | $9/month | $39/month | $19/month |
| Includes | 24B reads, 72M writes, 12GB | 10 billion rows, 10GB | 300 compute hours, 10GB |
| Overage model | Per billion rows | Per billion rows | Per compute hour |
Cost at Scale
For an application with 100 million reads/day and 1 million writes/day:
| Provider | Estimated Monthly Cost |
|---|---|
| Turso (Scaler) | $29 |
| PlanetScale (Scaler) | $39-80 |
| Neon (Scale) | $69-150 |
Turso is typically the cheapest due to its SQLite-based architecture and aggressive free tier.
Performance
Read Latency
| Provider | Same Region | Global (Edge) |
|---|---|---|
| Turso | 1-5ms | 5-20ms (edge replica) |
| PlanetScale | 5-15ms | 50-150ms (no edge) |
| Neon | 5-20ms | 50-150ms (no edge) |
Turso's edge replicas provide significantly lower global read latency.
Write Latency
| Provider | Latency | Notes |
|---|---|---|
| Turso | 20-80ms | Writes go to primary, replicated async |
| PlanetScale | 5-15ms | Writes in primary region |
| Neon | 5-20ms | Writes in primary region |
Turso has higher write latency because writes must reach the primary database. For read-heavy workloads (most web applications), this is not a problem.
Connection Model
| Provider | Connection Type |
|---|---|
| Turso | HTTP API (no persistent connections) |
| PlanetScale | MySQL protocol + HTTP API |
| Neon | PostgreSQL protocol + HTTP API |
Turso's HTTP API avoids connection pooling complexity entirely. PlanetScale and Neon support both traditional connections and serverless HTTP drivers.
Developer Experience
Turso + Drizzle
import { drizzle } from 'drizzle-orm/libsql'
import { createClient } from '@libsql/client'
const client = createClient({
url: process.env.TURSO_DATABASE_URL!,
authToken: process.env.TURSO_AUTH_TOKEN!,
})
const db = drizzle(client)
const users = await db.select().from(usersTable)
Neon + Drizzle
import { drizzle } from 'drizzle-orm/neon-http'
import { neon } from '@neondatabase/serverless'
const sql = neon(process.env.DATABASE_URL!)
const db = drizzle(sql)
const users = await db.select().from(usersTable)
PlanetScale + Drizzle
import { drizzle } from 'drizzle-orm/planetscale-serverless'
import { Client } from '@planetscale/database'
const client = new Client({ url: process.env.DATABASE_URL! })
const db = drizzle(client)
const users = await db.select().from(usersTable)
All three work well with Drizzle ORM. Setup is straightforward.
When to Choose Each
Turso
- Global edge applications (lowest read latency globally)
- Budget-conscious (generous free tier, lowest paid costs)
- Read-heavy workloads (blogs, content sites, read-mostly apps)
- Embedded use cases (SQLite at the edge)
- Multi-tenant applications (500 databases on free tier)
PlanetScale
- MySQL compatibility required (migrating from MySQL)
- Large-scale applications (Vitess is battle-tested at YouTube scale)
- Schema branching workflow (non-blocking schema changes)
- Enterprise requirements (SOC 2, HIPAA)
Neon
- PostgreSQL compatibility required (most common choice)
- Extensions needed (pgvector for AI, PostGIS for geo)
- Complex queries (PostgreSQL's query planner is superior)
- Branching for preview environments (branch per PR)
- Existing PostgreSQL expertise on the team
Our Default
We use Neon (PostgreSQL) as our default database for new projects. PostgreSQL's ecosystem (extensions, tooling, and community) is unmatched. Neon's branching feature integrates well with our Vercel preview deployment workflow.
For applications requiring global edge performance, we evaluate Turso.
Contact us to discuss database architecture for your application.