DEV Community

pickuma
pickuma

Posted on • Originally published at pickuma.com

Turso vs Neon: Serverless SQLite and Postgres Compared in 2026

Both Turso and Neon get filed under "serverless database," and that shared label hides the fact that they solve different problems. Turso is SQLite (via the libSQL fork) pushed to the edge, with the option to keep a real database file inside your application process. Neon is Postgres with compute and storage pulled apart so it can scale to zero and branch like git. If you pick one because it was trending, you'll feel the mismatch the first time your access pattern fights the architecture. We spent time with both to map where each design actually pays off.

Two different bets on "serverless"

Neon's core idea is structural: it separates the Postgres compute layer from a storage layer that holds your data as a log of page changes. Compute nodes spin up on demand, autoscale, and suspend when idle — so a project with no traffic costs you storage, not a running instance. Because storage is copy-on-write, Neon can create a branch of your entire database in roughly the time it takes to copy a pointer, not the time it takes to copy the data. That branching model is the feature people stay for: a branch per pull request, seeded from production-shaped data, torn down on merge.

Turso starts from a different place. It runs libSQL, an open-source fork of SQLite, and its defining move is the embedded replica: a local SQLite file that lives next to your application and syncs from a primary. Reads hit local disk — microseconds, not a network round trip — and writes go to the primary and replicate back. For read-heavy workloads where the same data is queried far more than it changes, that's a latency profile a networked Postgres simply can't match, because you've removed the network from the read path entirely.

The other Turso pattern worth naming is database-per-tenant. SQLite databases are cheap to create, so Turso encourages spinning up one database per user or per tenant instead of one shared schema with a tenant_id column on every table. That's a genuinely different data model, and it's awkward to replicate on Postgres.

In 2025 the Turso team began shipping a from-scratch rewrite of SQLite in Rust (the project formerly known as Limbo) alongside the existing libSQL engine. If you adopt Turso, check which engine your account is on and treat the newer engine as still-maturing rather than assuming full SQLite compatibility.

Where each one actually wins

Reach for Neon when your application is already Postgres-shaped. If you depend on JSONB, real foreign keys, window functions, pg_trgm, PostGIS, or any of the extension ecosystem, Neon gives you that without a porting exercise — it is Postgres, not a compatible-ish layer. The branching also changes how teams test: instead of a shared staging database that everyone corrupts, each branch is an isolated, production-like copy. For CI pipelines and preview deploys, that alone justifies the switch for a lot of teams.

Reach for Turso when read latency from many locations is the thing you're optimizing, or when the database-per-tenant model fits your product. A globally distributed app that mostly reads — documentation sites, config lookups, per-user state for a mobile or desktop client — benefits from data sitting on the same machine as the code. Turso also runs in places Postgres doesn't comfortably go: bundled into a mobile app, an edge function, or a CLI tool, because at the end of the day it's still SQLite.

The honest failure modes matter too. Turso's write story is the weaker side — writes funnel to a primary, so write-heavy or write-contended workloads lose the local-read advantage and inherit replication lag you have to reason about. Neon's scale-to-zero introduces cold starts: an idle compute node takes a moment to resume on the first query, which is fine for a background job and noticeable on a user-facing request. Neither is a dealbreaker, but both are real, and you want to know which one you're signing up for.

Cost shape and lock-in

The two price on different axes, which makes head-to-head dollar comparisons misleading until you know your own workload. Neon bills primarily on compute time (your autoscaling compute, measured while it's awake) plus storage. A spiky, mostly-idle app benefits because suspended compute isn't billed; a steadily busy app pays for steady compute. Turso bills around rows read, rows written, and storage, so a read-amplifying query pattern — say, an N+1 that reads the same rows thousands of times — shows up directly on the invoice in a way wall-clock compute pricing hides. Model your real query volume before committing; both have free tiers generous enough to do that honestly.

Lock-in cuts in opposite directions, and this is the most durable difference between them. Neon is standard Postgres, so your exit path is a pg_dump to any other Postgres host — the data and most of your queries move. What you'd lose is Neon-specific branching and autoscaling, not your schema. Turso is SQLite-compatible and libSQL is open source, so you can self-host or move the file, but the embedded-replica sync protocol and the database-per-tenant topology are Turso-shaped patterns you'd have to re-engineer elsewhere. Choosing either is partly a bet on which set of conveniences you're willing to build your application around.

Don't choose based on the "serverless" label alone. The decision that actually sticks is your read/write ratio and whether you need Postgres extensions. Read-dominant and edge-distributed leans Turso; write-balanced and extension-dependent leans Neon. Benchmark with your own query shapes on the free tier before you migrate anything.

Whichever you pick, you'll be writing the data-access layer, the migrations, and the connection handling — and getting the embedded-replica setup or the Neon branching workflow right is where the time goes. An AI-assisted editor that understands your codebase shortens that loop.


Originally published at pickuma.com. Subscribe to the RSS or follow @pickuma.bsky.social for new reviews.

Top comments (0)