Turso is a managed SQLite database service that runs your database at the network edge via HTTP, making it compatible with serverless and edge function environments where persistent TCP connections are not possible. It is the right database for read-heavy globally distributed apps, per-user database architectures, and teams that want SQLite's simplicity at production scale.
What Turso Actually Is
SQLite is the most widely deployed database in the world: it runs in browsers, mobile apps, embedded systems, and desktop applications. But SQLite is traditionally a file-based database that runs on a single machine with no network protocol. You can not connect to it from a different server.
Turso solves this with libSQL, a fork of SQLite that adds a network protocol. Your Turso database is a libSQL database running in Turso's infrastructure. You access it via HTTP using the Turso client library, or via WebSocket for lower-latency access in persistent server environments.
The 200+ edge locations mean Turso can run a replica of your database close to any user in the world. Reads are served from the closest replica. Writes go to the primary region and replicate asynchronously.
Why SQLite at the Edge
The traditional cloud database model has a fundamental latency problem: your database runs in one region (say, us-east-1), but your users are global. Every query from a user in Tokyo waits for a round trip to Virginia.
The conventional solution is read replicas: secondary database instances in different regions that serve reads. But managing read replica failover, replication lag, and consistency is operationally complex and expensive.
Turso's approach: SQLite is so lightweight that you can run a read replica in hundreds of edge locations cheaply. Because the database is just a file, replication is simpler than with Postgres or MySQL. Users read from the closest replica with minimal latency.
Why It Works in Serverless and Edge Functions
Serverless functions (AWS Lambda, Vercel Functions, Cloudflare Workers) have a fundamental incompatibility with traditional databases: they are stateless and cannot maintain persistent TCP connections. When a function finishes executing, any TCP connections it opened are abandoned. On the next invocation, a new connection must be opened. Opening a Postgres TCP connection takes 20-100ms per invocation, which adds up.
Turso's HTTP protocol sidesteps this entirely. HTTP is stateless by design: each query is an independent HTTP request. No persistent connection to manage. No connection pool. Each serverless function invocation sends an HTTP request to Turso and gets a response. The latency is a single HTTP round-trip, not a TCP handshake plus query.
For edge functions (Cloudflare Workers specifically), Turso uses WebSockets instead of HTTP for lower latency, and the Turso client handles reconnection automatically.
Per-User Databases: The Multi-Tenancy Pattern
One of Turso's distinctive features is that you can create thousands of SQLite databases cheaply. The free tier allows up to 500 databases. This enables a multi-tenancy pattern that is impossible with traditional databases: each user (or tenant) gets their own dedicated database.
The advantages of per-tenant databases:
Perfect isolation: a bug that corrupts one tenant's data cannot affect others. No multi-tenant query filters needed.
Independent scaling: you can move high-traffic tenants to higher-tier infrastructure without affecting others.
Compliance: GDPR deletion is a single DELETE DATABASE call. Tenant data never mingles.
Performance: small databases with one tenant's data are faster to query than a large shared database with millions of rows filtered by organization_id.
The disadvantage: cross-tenant analytics and reporting require querying hundreds or thousands of databases. Turso provides a Groups feature that makes this easier, but it is still more complex than querying a shared database.
The Turso Client
The Turso client library (@libsql/client) works in Node.js, Deno, and edge environments:
import { createClient } from '@libsql/client'
const client = createClient({
url: process.env.TURSO_DATABASE_URL!,
authToken: process.env.TURSO_AUTH_TOKEN!,
})
const result = await client.execute({
sql: 'SELECT * FROM users WHERE email = ?',
args: ['user@example.com'],
})
Turso works with Drizzle ORM using the drizzle-orm/libsql dialect, giving you type-safe queries on top of SQLite at the edge.
Limitations You Need to Know
Write latency: writes go to the primary region. If your primary is in us-east-1 and a user in Tokyo submits a write, the write latency is the round-trip time to us-east-1, not to the closest edge location. For write-heavy applications, this is a significant limitation.
Eventual consistency for reads: after a write, reads from non-primary replicas may return stale data briefly while replication propagates. Turso supports read-your-writes consistency for sessions (using a syncUrl that routes reads to primary after writes), but eventual consistency is the default.
Not for high write throughput: SQLite uses write-ahead logging and serializes writes. SQLite's write throughput on a single database tops out at a few thousand writes per second at best. If you need tens of thousands of writes per second, you need a database that distributes writes (Postgres with Citus, Cassandra, DynamoDB).
SQL subset: libSQL is SQLite, which has a smaller SQL feature set than Postgres or MySQL. No window functions in older SQLite versions (added in 3.25), no materialized views, limited ALTER TABLE support. If you are used to Postgres, you will occasionally hit these limitations.
Turso vs Traditional Databases for the Right Use Cases
Turso is excellent for:
- Read-heavy applications with globally distributed users
- Per-user or per-tenant isolated databases
- Serverless and edge function deployments where persistent connections are not possible
- Applications already using SQLite (mobile backends, offline-first apps) that need a server-side counterpart
Turso is not suited for:
- Applications with high write throughput
- Applications needing complex SQL (window functions, sophisticated JOINs, recursive CTEs)
- Strict consistency requirements where eventual consistency is unacceptable
Pricing
The free tier: 500 databases, 9GB total storage, 1 billion row reads per month. Generous enough for development, side projects, and early-stage products. The paid plans scale with storage and row reads.
Keep Reading
- Drizzle ORM Guide — type-safe queries on top of Turso's SQLite
- Postgres Guide for Developers — when you outgrow SQLite's write limits
- Vercel vs Cloudflare Pages vs Netlify — the edge deployment platforms Turso pairs with
Pristren builds AI-powered software for teams. Zlyqor is our all-in-one workspace — chat, projects, time tracking, AI meeting summaries, and invoicing — in one tool. Try it free.