Quick answer: Turso is distributed SQLite (built on the Apache-2.0 libSQL fork) with a genuinely large free Hobby plan — 9 GB storage, 500 databases, 1 billion row reads/month, 25 million writes, no credit card. It adds native vector search for RAG, Git-style database branches, and embedded replicas that sync a local SQLite file in your app for microsecond reads. It competes with Supabase and Neon on a different axis: read latency and per-tenant isolation rather than Postgres features.
Turso turned SQLite from “the database inside your phone” into a globally-replicated database your serverless functions read from in ~5 ms. It’s two layers: the open-source engine (libSQL, an Apache-2.0 SQLite fork that adds server mode, replication, native vector indexing, and an HTTP API — plus Limbo, a Rust rewrite with the same on-disk format), and the hosted platform with regional replicas and the free-tier ladder. Both engines are Apache 2.0, so you can self-host at any time.
Turso free Hobby plan at a glance
| Resource | Hobby (free) | Notes |
|---|---|---|
| Databases | Up to 500 | Cheap enough to give each customer their own |
| Total storage | 9 GB | Across all databases |
| Row reads | 1,000,000,000 / month | ~23 reads/sec sustained |
| Row writes | 25,000,000 / month | ~9.6 writes/sec sustained |
| Replica regions | 3 simultaneous | Primary plus two read replicas |
| Database branches | Included | Fork a DB like Git for preview envs |
| Embedded replicas | Included | Local SQLite file synced from the cloud primary |
| Vector indexes | Included |
F32_BLOB column + vector_top_k
|
| SDK languages | JS/TS, Python, Rust, Go, PHP | Plus a stateless HTTP API for serverless |
| Region control | You pick primary + replica locations | e.g. --location lhr, then add replicas |
| Sleeps / expires? | Standing plan, no trial expiry | Stay on Hobby indefinitely |
| Commercial use | Allowed on Hobby | No per-seat or revenue cap |
| Credit card | Not required | Sign up with GitHub |
Limits have moved as the engine matured — the turso.tech pricing page is the source of truth — but the shape is stable: more databases than Postgres free tiers, more reads than write-heavy tiers, and the only major host where embedded replicas are first-class.
Why distributed SQLite is suddenly useful
- Read-heavy apps with cheap geographic distribution. Most traffic is reads (a typical SaaS is ~95% SELECT). Serving reads from a same-region replica drops p95 from ~80 ms to ~5 ms; writes forward to the primary.
- Per-tenant databases. Opening a new SQLite database costs about as much as creating a file, so “one database per customer” becomes feasible — perfect isolation, trivial export-on-cancellation, easier compliance — instead of one shared Postgres with row-level security.
- Embedded replicas. The libSQL client keeps a full local SQLite file synced with the cloud primary. Reads hit the local file at on-disk speed (single-digit microseconds) while writes forward to the cloud — a real read replica living inside your process, ideal for feature flags, config, dashboards, and knowledge bases.
The 60-second walkthrough
# macOS / Linux
curl -sSfL https://get.tur.so/install.sh | bash
# Windows PowerShell: irm get.tur.so/install.ps1 | iex
turso auth signup # GitHub OAuth, Hobby plan by default
turso db create my-app --location lhr # London primary
turso db replicate my-app fra # add a Frankfurt read replica
npm install @libsql/client
import { createClient } from "@libsql/client";
const db = createClient({
url: process.env.TURSO_DB_URL, // libsql://my-app-yourorg.turso.io
authToken: process.env.TURSO_AUTH_TOKEN,
});
await db.execute(`CREATE TABLE IF NOT EXISTS notes (
id INTEGER PRIMARY KEY, body TEXT NOT NULL,
created_at INTEGER NOT NULL DEFAULT (unixepoch()));`);
await db.execute({ sql: "INSERT INTO notes (body) VALUES (?)", args: ["First note."] });
const result = await db.execute("SELECT * FROM notes ORDER BY id DESC LIMIT 5");
The same backend works from Python, Rust, Go, PHP, or a raw HTTP POST. To switch to an embedded replica, just add a local file and a sync URL — reads then hit local.db directly while writes still commit to the cloud:
const db = createClient({
url: "file:local.db",
syncUrl: process.env.TURSO_DB_URL,
authToken: process.env.TURSO_AUTH_TOKEN,
syncInterval: 60, // seconds; or call db.sync() manually
});
Vector search built into the schema
libSQL has a native vector type and nearest-neighbor index, so a RAG stack that normally needs a relational DB plus a separate vector DB (Pinecone, Qdrant, Chroma — see our free vector database guide) collapses into one schema:
CREATE TABLE chunks (
id INTEGER PRIMARY KEY, doc_id INTEGER NOT NULL, body TEXT NOT NULL,
embedding F32_BLOB(1024) NOT NULL -- 1024 = Cohere embed-v3 dim
);
CREATE INDEX chunks_embedding_idx ON chunks (libsql_vector_idx(embedding));
SELECT id, body, vector_distance_cos(embedding, ?) AS d
FROM chunks
WHERE rowid IN vector_top_k('chunks_embedding_idx', ?, 10)
ORDER BY d LIMIT 10;
It uses a DiskANN-style ANN index, so it stays fast into the millions of rows, and the embedding is just a column you can JOIN, filter, and back up like any other. Pair it with Cohere’s free embeddings API and the whole retrieval layer is one database with one SDK.
Database branches: Git, for schemas
Fork a database as a copy-on-write branch — the same preview-environment pattern Neon built for Postgres, plus the twist that your local dev database is itself just another branch:
turso db create staging --from-db production
turso db create pr-1234 --from-db production
Reading the free-tier edge
Reads are usually overprovisioned — 1 billion/month is ~23/sec sustained; embedded replicas take repeat reads off the meter entirely. Writes are easy to burn — 25 million/month is ~9.6/sec, so append-heavy logs, event sourcing, or save-on-keystroke UIs can blow through it; plan to compact or move to the Scaler plan ($29/mo) before launch. Storage is generous and egress is unmetered inside Turso’s network.
Where Turso wins, and where it doesn’t
Wins when your workload is read-heavy (microsecond embedded-replica reads at zero cost), you ship to multiple regions (3 free replica regions), your model is per-tenant (500 databases = one isolated DB per customer), you want local dev identical to prod (same engine, no drift), you need a vector index beside relational data, or you value open-source portability.
Loses when you need Postgres-specific features (JSONB+GIN, PostGIS, tsvector FTS, partial unique indexes) — reach for Supabase or Neon; you have a single huge write-heavy table (SQLite serializes writes per database); you run real OLAP (use DuckDB/ClickHouse); or your ORM assumes the Postgres dialect.
Turso vs Supabase vs Neon vs Cloudflare D1
- vs Supabase: Supabase is a batteries-included Postgres platform (auth, storage, edge functions; 500 MB DB free). Turso is a database only, but a lot of it (9 GB across 500 DBs). Pick Supabase for a whole backend; Turso when the database is all you want.
- vs Neon: Neon is serverless Postgres with branching and scale-to-zero (3 GB, ~190 compute hours free) — the closest Postgres analogue. If your team writes Postgres, Neon is lower-friction; if the per-tenant model resonates, Turso is more interesting.
- vs Cloudflare D1: D1 is also managed distributed SQLite (5M reads/day, 100K writes/day free) but lives inside the Workers ecosystem and has no embedded-replica equivalent. If your app is a Worker, D1 wins; if it’s a Node/Python/Go process elsewhere, Turso’s embedded replica wins on read latency.
The per-tenant SaaS pattern
Turso’s standout architecture: give every customer their own database. On signup, create a database from a template schema and store its token; on each request, connect to that tenant’s database.
// On signup
const dbName = `tenant-${tenantId}`;
await turso.databases.create({ name: dbName, group: "production", schema: "base-schema" });
const token = await turso.databases.createToken(dbName);
await saveTenantConnection(tenantId, dbName, token);
// On every request
const tenantDb = createClient({ url: tenant.dbUrl, authToken: tenant.token });
await tenantDb.execute("SELECT * FROM contacts");
You get five things free: no cross-tenant query risk, trivial export (“here’s your SQLite file”), trivial GDPR delete (“drop the database”), per-tenant backups, and per-tenant schema evolution. Hobby supports 500 such customers. To watch which queries are slow once you have users, the Turso dashboard surfaces per-database metrics; instrument LLM features with a free tracing layer like Langfuse.
FAQ
Do I need a credit card?
No. The Hobby plan is signup-with-GitHub, no payment method, and you can stay on it indefinitely.
Is libSQL the same as SQLite?
libSQL is a fork that stays on-disk-format compatible — a SQLite file opens in libSQL and vice versa (unless you use libSQL-only extensions like the native vector index). It adds server mode, replication, vector indexing, an HTTP API, and WASM UDFs that upstream SQLite declined.
What does “embedded replica” mean in practice?
Your app process keeps a local SQLite file synced with the cloud primary. Reads hit the local file at on-disk speed; writes forward to the cloud and replicate back. The file is durable across restarts, so only the first launch pays the full sync cost.
Can Turso handle vector search at scale?
Yes for typical RAG corpora (tens of thousands to a few million chunks) — libsql_vector_idx is an approximate-nearest-neighbor index, so query time stays sublinear. For hundreds of millions of vectors, a purpose-built vector database is still the right call. Vector storage counts against the 9 GB limit and queries count as normal reads — no separate pricing.
Can I use Turso from serverless (Workers, Vercel, Netlify)?
Yes — the libSQL HTTP client works in any environment that can make HTTPS requests, with a request-scoped connection model that suits serverless far better than databases needing a long-lived socket.
Getting started
Three commands: curl -sSfL https://get.tur.so/install.sh | bash, turso auth signup, turso db create my-app --location lhr. Install @libsql/client (or your language’s SDK), pass the URL and token, and write SQL. When you want zero-latency reads, add syncUrl and the same database becomes an embedded replica in your process. The free tier carries you far enough to ship.
Related Reads
- Supabase vs Neon: Which Free PostgreSQL Database Should You Use in 2026?
- Qdrant vs Pinecone vs Chroma: Free Vector Database
- Cohere Free API: The Best Free Embedding and Rerank API for RAG in 2026
- Best Free Hosting Platforms in 2026: Deploy for Free
- Render Free Hosting Review 2026: Deploy Web Apps, Databases, and Cron Jobs for Free
Originally published at toolfreebie.com.

Top comments (0)