Turso alternatives: libSQL hosting without row-read limits
libSQL is a fork of SQLite by the Turso team that adds the things SQLite always lacked: a network protocol, replication, and the ability to run as a server rather than just an embedded library. It's a great piece of work. The fact that the SQLite Consortium isn't accepting external contributions to SQLite proper means a fork like libSQL is the only realistic path to a more network-friendly SQLite-compatible engine, and Turso has invested heavily in making it good.
The hosting story is dominated by Turso (the company), and Turso is fine for plenty of workloads. Where it stops being fine is the moment you look at the row-read counter on your dashboard and realize your application is making a lot more database queries than you thought. Their pricing meters reads per row, not per request, and certain access patterns blow through the free and starter tiers faster than people expect. The recurring complaint on HN and elsewhere is "I thought this would be cheap and the bill surprised me."
If that resonates, this post is for you. Below: how libSQL hosting actually works in 2026, what each option costs you, and where the row-read trap shows up.
Contents
- The row-read pricing trap
- Option 1: Layerbase Cloud
- Option 2: Run it locally with SpinDB
- Option 3: Layerbase Desktop
- Option 4: Self-host libSQL
- Option 5: Plain SQLite
- Option 6: Cloudflare D1
- Which one to pick
The row-read pricing trap
Quick context for anyone who hasn't hit this yet. Turso's pricing meters two things: storage and "rows read." A row read is what it sounds like: every row your queries scan, including rows scanned to satisfy WHERE clauses that filter them out.
Some examples of queries that look cheap and aren't:
SELECT * FROM users WHERE email = 'x@example.com'on a table without an index onemail. Every row in the table gets scanned and counted as a read, even though you only return one.SELECT COUNT(*) FROM events WHERE created_at > '2026-01-01'. SQLite has to walk through enough of the table to count, which counts as reads.- Anything that does a full table scan for analytics-style queries. The scan is a lot of reads.
The official advice is to add indexes for every query pattern, which is good advice generally but means you need to be far more careful about access patterns than you'd be on a database with flat-rate pricing. The free tier covers a real chunk of usage, but applications with chatty query patterns can blow through it in unexpected ways.
This is fine if you're aware of it and design your queries accordingly. It's not fine if you assumed "SQLite is cheap" and the bill shows up at the end of the month.
Option 1: Layerbase Cloud
Layerbase Cloud hosts libSQL with flat per-instance pricing. No row-read meter. You pay for the database to exist, not for what your queries do inside it.
curl https://<your-host>.cloud.layerbase.dev/healthlibSQL on Layerbase runs the upstream libSQL server with TLS and HTTP-based access. You connect with the @libsql/client package, which is the standard libSQL client:
import { createClient } from '@libsql/client'
const client = createClient({
url: 'https://<your-host>.cloud.layerbase.dev',
authToken: '<your-token>',
})
const result = await client.execute(`SELECT * FROM users WHERE email = ?`, [
'x@example.com',
])
console.log(result.rows)The same client works against Turso, against a local libSQL server, and against Layerbase Cloud. No code changes when you switch.
What's different on Layerbase:
- Pricing is per instance, not per row read.
- Single-region by default. Turso's embedded-replicas-everywhere model is a real feature; we don't have an equivalent. If you need geo-distributed read replicas, Turso is the right answer.
- Scale-to-zero is on for free instances. libSQL cold-starts quickly.
When to pick Layerbase: you want a hosted libSQL with predictable pricing and you don't need geo-distributed replicas.
When to pick Turso: you specifically want the embedded-replicas-at-the-edge model and you've audited your queries enough to know what your row-read consumption will be.
Option 2: Run it locally with SpinDB
For local development, SpinDB runs a real libSQL server on your machine. Same binary as the upstream Turso project ships. (What is SpinDB?)
npm i -g spindb # npm
pnpm add -g spindb # pnpmCreate an instance:
spindb create libsql1 -e libsql --startGet the connection URL:
spindb url libsql1http://127.0.0.1:8080That's a real libSQL server with HTTP access. Point the @libsql/client package at it during development, then swap to Layerbase Cloud or Turso for production by changing the URL.
spindb stop libsql1
spindb start libsql1
spindb listA common pattern: develop against SpinDB's libSQL locally, deploy to Layerbase Cloud (or Turso, if that fits) for production. Same client code, just different connection details.
Option 3: Layerbase Desktop
Layerbase Desktop gives you the SpinDB experience in a Mac app. Useful for libSQL specifically because it gives you a stable place to manage local instances without remembering ports or auth tokens. New instance, pick libSQL, copy the URL.
If you're prototyping a SQLite-replacement architecture and want to keep a libSQL handy for quick experiments, Desktop is the easiest setup.
Option 4: Self-host libSQL
The libSQL server is open source. The repo is at github.com/tursodatabase/libsql and there's an sqld binary you can run on any VM:
sqld --http-listen-addr 0.0.0.0:8080 --grpc-listen-addr 0.0.0.0:5001You're responsible for TLS, auth tokens, backups, and replication if you want any. Doable, especially for a small workload. The big trade-off: libSQL's interesting features (embedded replicas, vector search, server-side migrations) require some infrastructure work to wire up correctly.
If you do go this route, set up off-host backups before you put anything important in the database. libSQL's WAL-based replication makes streaming backups straightforward, but only if you bother to set it up.
Option 5: Plain SQLite
Worth flagging because it's often the right answer and people overlook it. If you're embedding a database in an application (a desktop app, a Tauri app, a CLI tool, a backend that runs on a single server), plain SQLite is fine. You don't need libSQL. SQLite is the most-deployed database in the world and the embedded use case is exactly what it was designed for.
The reasons to reach for libSQL over plain SQLite are specific:
- You need network access from multiple clients.
- You need replication.
- You want vector search.
- You want server-side migrations applied during deploys.
If none of those apply, plain SQLite with better-sqlite3 (Node) or sqlite3 (Python) or your language's equivalent is simpler and faster.
Layerbase Cloud also hosts plain SQLite (behind the same PG-wire trick we use for DuckDB) if you want hosted SQLite without the libSQL layer. It's a niche use case but it exists.
Option 6: Cloudflare D1
D1 is Cloudflare's SQLite-based database that runs on their Workers platform. Different sweet spot than Turso or Layerbase: it's designed for low-latency reads from edge functions, not as a general-purpose hosted SQLite. If your application is a Cloudflare Worker, D1 is great. If your application runs anywhere else, D1 is awkward because you can only reach it through a Worker.
The pricing model is friendlier than Turso's row-read meter (Cloudflare meters reads in larger units), but the lock-in to the Workers platform is real. Pick D1 if you're already on Workers. Pick something else otherwise.
Which one to pick
Short version:
- Want hosted libSQL with flat pricing? Layerbase Cloud.
- Running libSQL locally for development? SpinDB.
- Want the same in a Mac app? Layerbase Desktop.
- Need geo-distributed embedded replicas and have audited your query patterns? Turso.
- Building on Cloudflare Workers? D1.
- Embedding a database in a desktop app or single-server backend? Plain SQLite, no libSQL needed.
The libSQL project itself is in great shape. The fork has aged well, the server (sqld) is solid, and the client libraries are mature. The thing that often goes wrong is the hosting decision, where people pick Turso without auditing query patterns and get surprised by row-read bills. If that's you, Layerbase Cloud and the other options above are worth a look.
For more on the engine itself, getting started with libSQL walks through the protocol, replication model, and TypeScript client with a real example.