Quick verdict
Choose Cloudflare D1 if your application runs on Cloudflare Workers or Pages: the database is a binding in your Worker configuration, there are no egress charges, Time Travel point-in-time restore is always on (7 days on Workers Free, 30 days on Workers Paid), and you can create thousands of databases. Choose Turso if you need to reach the database from many runtimes and clouds, want reads from a local file inside your app or offline sync, need more than 10 GB in one database, or want an open source (MIT) engine you could also run yourself. Both suit a database per user or tenant.
Cloudflare D1 is, in Cloudflare's words, a "managed, serverless database with SQLite's SQL semantics, built-in disaster recovery, and Worker and HTTP API access." You create a database with Wrangler, declare it as a binding in your Worker's configuration and call it from code as env.DB. Cloudflare documents that D1 "is designed for horizontal scale out across multiple, smaller (10 GB) databases, such as per-user, per-tenant or per-entity databases."
Turso runs Turso Cloud, a managed platform for SQLite-compatible databases, and develops two MIT-licensed engines: Turso Database, a Rust rewrite of SQLite that Turso calls its intended direction (pre-1.0, v0.8.2 on 6 October 2026), and libSQL, its earlier SQLite fork, which is maintained while new features go to Turso Database. Apps query Turso Cloud over the network, or keep a local copy through embedded replicas or Turso Sync.
For the engine itself against PostgreSQL, see SQLite vs PostgreSQL; for Turso against a Postgres backend, see Turso vs Supabase.
Side by side
| Aspect | Cloudflare D1 | Turso |
|---|---|---|
| Platform | Part of Cloudflare Workers; also an HTTP API | Independent service; clients for many languages and runtimes |
| Engine | SQLite semantics, run by Cloudflare | Turso Database (Rust, pre-1.0) or libSQL; both MIT |
| Maximum database size | 500 MB on Workers Free; 10 GB on Workers Paid (cannot be raised) | No per-database cap documented; plan storage 5 GB Free up to 50 GB Pro, then overage |
| Databases per account | 10 on Workers Free; 50,000 on Workers Paid | 100 on Free; unlimited on paid plans |
| Backups and restore | Time Travel to any minute: 7 days Free, 30 days Paid, no extra cost | Point-in-time history: 1 day Free, 10 days Developer, 30 days Scaler, 90 days Pro |
| Read scaling | Read replication in public beta, via the Sessions API, no extra charge | Embedded replicas and Turso Sync (local copies); Edge Replicas deprecated for new users |
| Concurrency | Each database is single-threaded and processes queries one at a time | Turso Database adds BEGIN CONCURRENT (MVCC) for concurrent writes |
| Data residency | Jurisdictions at creation: eu, fedramp and us | AWS-based Turso Cloud; no jurisdiction option documented on the pages we checked |
| Main trade-off | Closest fit for Workers, but tied to Cloudflare and capped at 10 GB per database | Portable and local-first, but a separate vendor and an engine in transition |
Key differences
The Workers binding versus a portable client
D1 is designed around Cloudflare Workers. You create a database with npx wrangler@latest d1 create prod-d1-tutorial, add a d1_databases entry (binding name, database name and ID) to your Wrangler configuration, and the Worker receives the database on env. Queries use prepared statements with ? placeholders. Adapted from Cloudflare's getting-started guide and Worker API reference:
// TypeScript, Cloudflare Worker with a D1 binding named DB
export default {
async fetch(request, env) {
const { results } = await env.DB.prepare(
"SELECT * FROM Customers WHERE CompanyName = ?",
)
.bind("Bs Beverages")
.run();
return Response.json(results);
},
};run() returns a result object with results, success and meta (including rows_read and rows_written); Cloudflare notes that all() is functionally equivalent. first() returns one row, and batch() sends several statements in one call. Outside Workers, D1 is reachable through Cloudflare's HTTP API.
Turso is not tied to a host platform. Its TypeScript client, shown in Turso's SDK reference, works the same from Node.js, serverless functions or other runtimes:
// TypeScript, @libsql/client (Turso Cloud)
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 id = ?",
args: [1],
});Turso now recommends @tursodatabase/database for local and embedded use and @tursodatabase/serverless for remote access, keeping @libsql/client for ORMs and remote libSQL; check its docs for the package that fits your runtime.
Limits that shape the design
Cloudflare's limits page sets D1's boundaries. On Workers Paid: 10 GB per database ("the 10 GB limit of a D1 database cannot be further increased"), 1 TB of storage per account, 50,000 databases per account and 1,000 queries per Worker invocation. On Workers Free: 500 MB per database, 5 GB per account, 10 databases and 50 queries per invocation. On all plans: 30 seconds maximum query duration, 100 KB maximum SQL statement, 100 bound parameters per query, 100 columns per table and 2 MB per row, string or BLOB. Cloudflare also documents that each database "is inherently single-threaded, and processes queries one at a time", giving the example that 1 ms queries allow about 1,000 queries per second. Since 1 September 2026, queries on Workers Free fail once the account exceeds the daily row limits, until they reset at midnight UTC.
Turso's pricing page limits plans by storage, rows read and written, and sync volume rather than per-database size, and paid plans allow unlimited databases. Turso Cloud documents some SQLite differences: PRAGMA user_version and application_id are read-only, and busy_timeout and journal_mode are not supported. Turso Database adds BEGIN CONCURRENT for concurrent writers, where conflicting transactions must roll back and retry.
Read replication and local copies
D1 read replication creates read-only copies in several regions (Cloudflare lists ENAM, WNAM, WEUR, EEUR, APAC and OC) at no extra charge. It was announced as a public beta on 10 April 2025, and the D1 changelog shows no general availability announcement as of October 2026. You enable it per database and must use the Sessions API; otherwise all queries go to the primary. A session started with env.DB.withSession() gives sequential consistency, and passing the bookmark back on the next request keeps a user's reads consistent with their writes.
Turso has moved the other way: its Edge Replicas (copies in many locations) are deprecated for new users, and it puts the copy in your app instead. An embedded replica reads locally and sends writes to the cloud primary; Turso Sync, recommended for new projects that need sync, adds local writes with explicit push() and pull(). Both need a filesystem, so they suit servers, desktop and mobile apps more than Workers-style runtimes.
Backups: Time Travel versus point-in-time history
D1 Time Travel is always on and needs no setup. It restores a database to any minute within the last 30 days on Workers Paid (7 days on Free), with wrangler d1 time-travel restore, and Cloudflare states that "database history and restoring a database incur no additional costs". Restores are limited to 10 per 10 minutes per database.
Turso Cloud includes point-in-time recovery whose window grows with the plan (1 day on Free up to 90 days on Pro and Enterprise) and can recover deleted databases for up to five days. Turso also offers branching on paid plans: a branch is a new database created from an existing one, counted against your database quota.
Pricing and licensing
Cloudflare D1. Listed on Cloudflare's D1 pricing page in October 2026, in USD. Workers Free: 5 million rows read per day, 100,000 rows written per day, 5 GB storage in total. Workers Paid (minimum charge 5 USD per month per account): 25 billion rows read per month included, then 0.001 USD per million rows; 50 million rows written per month included, then 1.00 USD per million rows; 5 GB storage included, then 0.75 USD per GB-month. Cloudflare states there are no egress or bandwidth charges, no charge for compute hours, and no extra charge for read replicas.
Turso. Listed on the Turso pricing page in October 2026, in USD. Free: 0 USD, 100 databases, 5 GB storage, 500 million rows read and 10 million rows written per month, 3 GB of syncs, 1 day of history. Developer: 4.99 USD per month (a saving is shown for yearly billing), unlimited databases, 9 GB storage then 0.75 USD per GB, 2.5 billion rows read then 1 USD per billion, 25 million rows written then 1 USD per million, 10 days of history. Scaler: listed at 24.92 USD per month, 24 GB storage, 100 billion rows read, 100 million rows written, 30 days of history. Pro: listed at 416.58 USD per month, 50 GB storage, 90 days of history. Enterprise: custom.
Both bill mainly by rows read, rows written and storage, so the cost of a query depends on how many rows it scans: indexes matter on both. D1's cost sits inside a Workers Paid account; Turso is a separate bill.
Pricing checked on the vendors' official pages on 7 October 2026. Prices change; confirm before buying.
Where each one leads
Cloudflare D1 strengths
- Binding API inside Workers: no connection strings or tokens in application code
- Time Travel restore to any minute, always on, at no extra cost
- No egress or bandwidth charges, and no compute-hour billing
- Up to 50,000 databases per account on Workers Paid
- Data residency jurisdictions (eu, fedramp, us)
Turso strengths
- Usable from any platform and language, not one cloud
- Embedded replicas and Turso Sync for local reads and offline-capable apps
- No documented per-database size cap like D1's 10 GB
- MIT-licensed engines that can also run embedded without the cloud
- Concurrent writes with BEGIN CONCURRENT in Turso Database
Limitations
Cloudflare D1 limitations
- 10 GB maximum per database (500 MB on Workers Free), which cannot be raised
- Each database is single-threaded and processes queries one at a time
- Read replication is still in public beta and needs the Sessions API
- Designed around Cloudflare Workers; access from elsewhere is through the HTTP API
- Workers Free queries fail once daily row limits are exceeded
Turso limitations
- Turso Database is pre-1.0 and libSQL now receives maintenance rather than new features
- Edge Replicas are deprecated for new users
- Local replicas need a filesystem, which many edge runtimes lack
- Some SQLite pragmas are read-only or unsupported on Turso Cloud
When to choose each
Choose Cloudflare D1 if
- Your application already runs on Cloudflare Workers or Pages
- Each database will stay under 10 GB, for example per user or per tenant
- You want built-in point-in-time restore with no setup or extra cost
- You need EU, FedRAMP or US data jurisdiction at database creation
Choose Turso if
- You deploy to several clouds or runtimes, or not to Cloudflare at all
- You want reads from a local file in the app, or sync to devices
- A single database may grow beyond 10 GB
- You want an open source engine you could run yourself
When neither is right
- You need PostgreSQL features or branching with data: see Turso vs Neon and Supabase vs Neon.
- You want auth, storage and APIs with the database: see Turso vs Supabase and Supabase vs Firebase.
- Your workload is analytical rather than transactional: see DuckDB vs SQLite.
- You need one large relational database with heavy concurrent writes: a client-server engine fits better; see SQLite vs PostgreSQL.
Final recommendation
If you build on Cloudflare Workers, D1 is the simpler choice: a binding instead of a connection, always-on Time Travel and no egress charges, provided each database stays within 10 GB and you design for many small databases. If you need the database outside Cloudflare, local reads inside your app, or databases that may outgrow 10 GB, Turso is the more flexible option, keeping in mind that its newest engine is still pre-1.0. Both use SQLite semantics, so moving a schema between them is usually easier than moving to Postgres.
Frequently asked questions
What is the maximum size of a Cloudflare D1 database?
10 GB on the Workers Paid plan and 500 MB on Workers Free. Cloudflare states that the 10 GB limit cannot be increased and recommends splitting data across multiple smaller databases, such as one per user or tenant.
Is D1 read replication generally available?
As of October 2026 it is still a public beta, announced on 10 April 2025. It has no extra charge, is enabled per database, and only applies to queries made through the Sessions API (withSession()).
Can I use D1 outside Cloudflare Workers?
Yes, through Cloudflare's HTTP API, but D1 is designed around the Worker binding. If most of your code runs elsewhere, a service with native clients for your runtime, such as Turso, may fit better.
Is Turso the same as libSQL?
No. libSQL is Turso's earlier fork of SQLite, still maintained. Turso Database is a newer Rust rewrite of SQLite that Turso describes as its intended direction. Turso Cloud hosts databases of both kinds.
Does D1 Time Travel cost extra?
No. Cloudflare states that database history and restoring a database incur no additional costs. History covers 30 days on Workers Paid and 7 days on Workers Free.
Sources
- Cloudflare D1 documentation
- Cloudflare D1: Limits
- Cloudflare D1: Pricing
- Cloudflare D1: Time Travel
- Cloudflare D1: Read replication
- Cloudflare D1: Workers Binding API
- Cloudflare D1 changelog
- Cloudflare Workers pricing
- Turso pricing
- Turso docs: Turso Cloud
- Turso docs: Embedded replicas
- Turso docs: TypeScript SDK
- Turso Database (GitHub repository, MIT)
Checked October 2026.
How we research comparisons: our editorial method.