- SQL over HTTP — Every query is sent over the network to the database. Simple to set up and works in any runtime, including edge functions, without filesystem access. This is the model you already know from every other database.
- In-Function SQLite — Database pages are replicated into the serverless function. Reads execute locally with no network round-trips; writes go directly to the remote database for durability. If you’ve used Turso’s embedded replicas or Cloudflare’s Durable Objects with SQLite, this model will feel familiar. See Bringing SQLite to Vercel Functions for a deep dive.
| SQL over HTTP | In-Function SQLite | |
|---|---|---|
| Packages | @tursodatabase/serverless, @libsql/client | @tursodatabase/vercel-experimental |
| Best for | Write-heavy workloads, edge runtimes without filesystem | Read-heavy workloads, per-tenant databases |
| Read latency | Network round-trip per query | In-process SQLite read (zero network hops) |
| Write latency | Network round-trip | Network round-trip (same) |
| Multi-tenant | Shared database | Database-per-tenant with automatic on-demand provisioning |
| Runtime requirements | fetch API only | Ephemeral filesystem (/tmp) |
| ORM support | Drizzle, Prisma, and others (@libsql/client) | Not yet supported |
SQL over HTTP
Connect to Turso databases from Vercel serverless and edge environments. Configure your Vercel environment with the following variables:TURSO_DATABASE_URL— Your Turso database URLTURSO_AUTH_TOKEN— Your Turso auth token
@tursodatabase/serverless | @libsql/client | |
|---|---|---|
| Status | Beta | Production-ready |
| Dependencies | Uses only fetch — zero native dependencies | Requires Node.js or /web subpath |
| Concurrent writes | Planned | Will not be supported |
| ORM support | Not yet supported | Drizzle, Prisma, and others |
@tursodatabase/serverless is the lightest option with zero native dependencies — and will be the driver to later support concurrent writes. Use @libsql/client if you need a battle-tested driver today with ORM integration.
Quickstart
- @tursodatabase/serverless (beta)
- @libsql/client
The For compatibility with the libSQL client API, use the compat module:
@tursodatabase/serverless package connects to Turso using only the fetch API — no native dependencies, making it the smallest option for edge and serverless runtimes.In-Function SQLite
The@tursodatabase/vercel-experimental package replicates SQLite database pages into the serverless function itself. Reads execute against the local copy with no network round-trips. Writes go directly to the remote database for durability and consistency. This approach is ideal for read-heavy workloads where per-query network latency is the dominant cost.
- Per-tenant isolation and sharding — Each agent, workspace, or session can have its own database with independent storage limits
- Colocation of compute and data — Business logic runs next to the database, enabling zero-hop reads and many queries per request
- Automatic on-demand provisioning — Databases are created implicitly when
createDb()is called, no redeploy or binding management needed
Quickstart
Install the package:The
TURSO_GROUP environment variable scopes all database access to a single group. Even though the API token grants access to the entire organization, an attacker who controls the database name can only access databases within the configured group. The database name is still recommended to be stored as a secret environment variable when possible.createDb() to open a database and start querying:
Per-tenant databases
The auto-provisioning makes it straightforward to implement a database-per-tenant pattern. Instead of routing all tenants through a single shared database, each user or session gets its own isolated SQLite database. Simply derive the database name from a tenant identifier:API Reference
createDb(name, options?)
Creates or retrieves a database instance. If the database does not exist, it is created automatically within the configured group (TURSO_GROUP). Calling createDb() with the same name within a single function invocation returns the existing instance.
remoteWrites is true (the default), write statements (INSERT, UPDATE, DELETE) are sent directly to the remote Turso database for immediate durability. When set to false, writes are applied to the local SQLite copy and pushed in a single batch when db.push() or db.close() is called. This can be useful for bulk ingestion or background tasks where eventual visibility is acceptable.
db.query(sql, params?)
Execute a SELECT query and return results.
db.execute(sql, params?)
Execute an INSERT, UPDATE, DELETE, or DDL statement. By default, writes are sent directly to the remote Turso database. If remoteWrites: false is set, writes are applied locally and pushed on close().
db.close()
Close the connection. If remoteWrites: false is set, this also pushes any pending local writes to the remote Turso database. Always call this in a finally block. As a safety net, the package registers a callback with Vercel’s waitUntil() API to push pending changes if close() is not called within 5 seconds of function completion.
db.push()
Manually push local changes to the remote Turso database without closing the connection. Only applicable when using remoteWrites: false.
db.pull()
Pull latest changes from the remote Turso database.