· turso / cloudflare / d1
Turso vs Cloudflare D1: Chọn SQLite nào cho Edge?
D1 là lựa chọn hiển nhiên nếu bạn dùng toàn bộ Cloudflare Workers. Turso là lựa chọn cho mọi runtime khác. Đây là dữ liệu đằng sau quyết định đó.
Bởi toolchew
2.239 từ · 12 phút đọc
Dùng Cloudflare D1 nếu toàn bộ stack của bạn chạy trên Cloudflare Workers và bạn muốn setup database đơn giản nhất có thể. Dùng Turso nếu bạn cần database hoạt động trên Node.js, Bun, Deno, Vercel, hay bất kỳ runtime nào ngoài Cloudflare. Đó là ranh giới cốt lõi. Mọi thứ phía dưới là bằng chứng.
Bài viết này dành cho ai
Developer đang cân nhắc edge hoặc serverless SQLite vào năm 2026. Nếu bạn đã gắn bó với một nền tảng và hài lòng với nó, bài viết này sẽ không thuyết phục bạn đổi — nhưng sẽ cho bạn biết mình đang bỏ qua gì.
TL;DR
| Turso | Cloudflare D1 | |
|---|---|---|
| Lượt đọc free tier | 500M rows/tháng | 5M rows/ngày (~150M/tháng) |
| Gói paid thấp nhất | $4.99/tháng | $5/tháng (Workers Paid base) |
| Topology ghi | Primary một region + replica tùy chọn | Primary một region |
| Khả năng di chuyển SDK | Node, Bun, Deno, edge runtimes, mobile | Chỉ qua Cloudflare Workers binding |
| Hỗ trợ ORM | Drizzle ✓, Prisma ✓ (Migrate ✗) | Drizzle ✓, Prisma Preview (transactions ✗) |
| Vendor lock-in | Thấp — libSQL là open-source | Cao — Workers binding là proprietary |
Giá cả
D1 free tier chạy theo giới hạn hàng ngày: 5M dòng đọc và 100K dòng ghi mỗi ngày, 5 GB tổng dung lượng, tối đa 10 database. Nếu traffic đều đặn, bạn chỉ đạt khoảng 150M lượt đọc mỗi tháng. Gói paid thêm D1 mà không tính phí nền tảng riêng, trên nền $5/tháng của Workers Paid: bao gồm 25 tỷ dòng đọc và 50 triệu dòng ghi mỗi tháng. Phí vượt mức là $0.001 mỗi triệu lượt đọc và $1.00 mỗi triệu lượt ghi. Dung lượng trên 5 GB đầu tiên có giá $0.75/GB mỗi tháng.
Turso free tier tính theo tháng: 500M dòng đọc, 10M dòng ghi, 5 GB dung lượng, 100 database. Gói Developer ở $4.99/tháng nâng lên 2.5B lượt đọc, 25M lượt ghi, 9 GB dung lượng, và unlimited database. Gói Scaler ở $24.92/tháng và Pro ở $416.58/tháng thêm headroom cho reads, writes, storage, và point-in-time restore.
Với các ứng dụng đọc nhiều, free tier của Turso rõ ràng hào phóng hơn — 500M lượt đọc/tháng so với trần thực tế khoảng 150M của D1. Ở quy mô paid, 25B lượt đọc của D1 cho $5/tháng base khó ai cạnh được. Cả hai đều tính $1.00 mỗi triệu lượt ghi vượt giới hạn, con số này tích lũy nhanh với workload ghi nhiều.
Một điểm cần lưu ý với D1: free tier giới hạn 50 queries mỗi lần gọi Worker. Các trang phức tạp với nhiều query nhỏ — lấy thông tin user, preferences, feed — có thể chạm giới hạn này trước cả giới hạn row. Gói paid nâng lên 1.000, hiếm khi là vấn đề.
Data model: libSQL và managed SQLite
Turso chạy libSQL, một open-source fork của SQLite do Turso duy trì vì upstream SQLite không nhận contribution từ bên ngoài. Tương thích 100% với SQLite — cùng định dạng file, cùng API, cùng SQL dialect. Ngoài SQLite thuần, libSQL thêm kiểu vector native (F32_BLOB với DiskANN indexing), một native replication protocol qua gRPC, và hỗ trợ browser/WASM.
Turso đang trong giai đoạn chuyển đổi lớn hơn: Turso Database engine mới (trước đây là Limbo) là bản viết lại hoàn toàn bằng Rust của SQLite với concurrent writes và async I/O, hiện đang trong beta. Engine C-based libSQL đang vận hành Turso Cloud ngày nay. Các dự án mới cần async I/O hoặc concurrent writes có thể dùng thử beta qua @tursodatabase/database.
D1 chạy trên Cloudflare-managed SQLite-compatible storage. Cloudflare không công bố phiên bản cụ thể; theo nghiên cứu cộng đồng thì là SQLite 3.46 với compatibility_date >= 2024-09-23, được cập nhật qua hệ thống compatibility date thay vì một pin cố định. D1 không hỗ trợ interactive transactions — không có cú pháp SQL BEGIN/COMMIT/ROLLBACK. Thứ nó có là batch() API: thực thi một danh sách statements như một atomic SQL transaction và rollback toàn bộ batch khi có lỗi. Điều bạn không thể làm là mở một transaction, kiểm tra kết quả trung gian, rồi commit hoặc rollback theo điều kiện — đó là interactive transaction control, và D1 không có.
Topology replication
Turso dùng mô hình group: một primary region, không hoặc nhiều replica locations. Đọc phục vụ từ replica gần nhất. Ghi đi đến primary; replica tự động forward writes. Các region có sẵn: Tokyo, Mumbai, Ireland, Virginia, Ohio, và Oregon — tất cả trên AWS.
Có một lưu ý quan trọng cho người dùng mới: geographic replication (edge replicas) đã bị ngừng. Turso cho biết 70% người dùng chưa bao giờ tạo replica, nên tính năng này đang bị thu hồi để nhường chỗ cho giải pháp data-locality tốt hơn, vẫn đang phát triển. Khách hàng paid cũ vẫn giữ quyền truy cập; tài khoản mới bắt đầu với single-region primary.
Turso cũng từng có embedded replicas — một file SQLite local đồng bộ với Turso Cloud với lượt đọc microsecond tại chỗ. Cách này cần persistent filesystem, nên không dùng được trên Cloudflare Workers. Turso hiện khuyến nghị Turso Sync thay thế: các lệnh push() và pull() tường minh cho TypeScript, Python, và Go, không cần filesystem.
D1 giữ writes ở một primary region duy nhất được chọn lúc tạo database. Global read replication đã vào public beta vào tháng 4/2025. Khi bật, D1 tự động tạo read-only replicas trên cả sáu region hỗ trợ với độ trễ replication khoảng 30–75ms. Để dùng, bạn opt in qua Sessions API:
const session = env.DB.withSession("first-primary");
const result = await session.prepare("SELECT * FROM users").all();
Nếu không dùng withSession(), mọi query đều đi về primary bất kể replica đang ở đâu. Sessions API chỉ có qua Worker binding, không có qua REST API.
SDK và khả năng di chuyển runtime
Đây là điểm hai sản phẩm khác nhau rõ nhất.
Turso cung cấp ba packages:
@tursodatabase/serverless— không có native dependency, hoạt động ở bất kỳ đâu cófetch(Node 12+, Deno, Cloudflare Workers, Vercel Edge, Netlify Edge)@libsql/client— ORM integration package, native trên Node.js, với@libsql/client/webcho edge runtimes@tursodatabase/database— local-first, dùng Turso Database engine mới, beta
Bạn có thể query Turso từ một Next.js API route trên Vercel, một Node.js backend trên AWS, một Deno Deploy function, hay một Cloudflare Worker — cùng library, cùng SQL.
D1 chỉ dùng được trên Workers. Truy cập qua environment binding khai báo trong wrangler.toml và được inject lúc runtime:
const result = await env.DB.prepare(
"SELECT * FROM users WHERE id = ?"
).bind(userId).all();
// Batch nhiều statements trong một round-trip
const [users, posts] = await env.DB.batch([
env.DB.prepare("SELECT * FROM users"),
env.DB.prepare("SELECT * FROM posts"),
]);
Cloudflare có REST API cho external access, nhưng chính tài liệu của họ mô tả nó là “phù hợp nhất cho mục đích quản trị” do giới hạn rate toàn cầu của API. Với external access trong production, cách khuyến nghị là xây một proxy Worker — một HTTP layer mà code bên ngoài gọi vào. Đó là thêm infrastructure trên critical path.
Nếu bất kỳ phần nào của stack bạn chạy ngoài Cloudflare Workers, D1 cần một proxy. Turso thì không.
Hỗ trợ ORM
Drizzle hoạt động tốt với cả hai. Với Turso, set dialect thành "turso" trong config và dùng @libsql/client:
import { drizzle } from 'drizzle-orm/libsql';
import { createClient } from '@libsql/client';
const client = createClient({
url: process.env.TURSO_URL!,
authToken: process.env.TURSO_TOKEN!,
});
export const db = drizzle(client);
Với D1, truyền trực tiếp binding:
import { drizzle } from 'drizzle-orm/d1';
const db = drizzle(env.DB);
Drizzle Kit dùng driver d1-http cho migrations với D1 qua REST API — đây là path chỉ dùng trong development, không phải production.
Prisma hoạt động với cả hai, nhưng mỗi bên có giới hạn riêng.
Với Turso (Prisma 5.4.2+): cần @prisma/adapter-libsql. Prisma Migrate và Introspection không được hỗ trợ. Cách xử lý là tạo migrations local với SQLite rồi apply qua turso db shell <db> < migration.sql.
Với D1 (Prisma v5.12.0+, Preview tính đến 2026): cần @prisma/adapter-d1. D1 không có interactive transactions, nên Prisma $transaction() API không được hỗ trợ. Prisma ORM 6.6.0 (tháng 4/2025) thêm D1 migrations trong Early Access qua các lệnh CLI riêng: prisma db push (cập nhật schema), prisma db pull (introspection), và prisma migrate diff. Lưu ý: prisma migrate dev và prisma migrate deploy chưa được hỗ trợ tại thời điểm đó.
Trên thực tế: nếu team bạn dùng Prisma Migrate như một workflow chính, không adapter nào hỗ trợ nó tốt. Migration story của Drizzle mượt hơn trên cả hai nền tảng. Để so sánh chi tiết giữa Drizzle và Kysely, xem Drizzle vs Kysely. Nếu bạn muốn góc nhìn tổng quan các lựa chọn TypeScript ORM trong 2026, xem TypeScript ORM tốt nhất 2026.
Giới hạn và quota
| Giới hạn | Turso Free | Turso Developer ($4.99/tháng) | D1 Free | D1 Paid ($5/tháng base) |
|---|---|---|---|---|
| Số database | 100 | Unlimited | 10 | 50.000 |
| Kích thước DB tối đa | Không công bố | Không công bố | 500 MB | 10 GB |
| Tổng dung lượng | 5 GB | 9 GB | 5 GB | Đến 1 TB |
| Dòng đọc | 500M/tháng | 2.5B/tháng | 5M/ngày | 25B/tháng |
| Dòng ghi | 10M/tháng | 25M/tháng | 100K/ngày | 50M/tháng |
| Transactions | Có | Có | Không có BEGIN/COMMIT; batch() là atomic | Không có BEGIN/COMMIT; batch() là atomic |
| Queries/invocation | Không giới hạn | Không giới hạn | 50 | 1.000 |
| Hành vi khi vượt giới hạn | BLOCKED error | BLOCKED error | Request thất bại | Tính phí mỗi triệu |
Turso không công bố giới hạn kích thước mỗi database; storage được tính ở cấp tài khoản trên tất cả database theo đơn vị 4 KB page. Khi vượt giới hạn Turso, queries trả về error code BLOCKED thay vì xếp hàng hoặc giảm cấp độ phục vụ.
Các tình huống thực tế
Xây SaaS trên Cloudflare Workers. D1 là lựa chọn mặc định ở đây. Không cần connection string, không có infrastructure database riêng, giá cả minh bạch. Workers binding chặt hơn bất kỳ cách nào dùng client library — bạn không thể cấu hình sai vì không có gì để cấu hình ngoài wrangler.toml. Giới hạn 10 GB mỗi database và 50.000 database giúp SaaS multi-tenant khả thi. Giới hạn 50 queries/invocation ở free tier là thứ cần tính đến sớm.
Xây code portable không gắn với Cloudflare. Turso. Data access layer của bạn hoạt động trên Node.js, Deno, Vercel, Netlify, hay bất kỳ đâu. libSQL client là SQL chuẩn — không có binding injection, không có proxy Worker. Khi cần chạy integration test local hay chuyển sang host khác, bạn không phải xây lại data layer.
Stack hỗn hợp — Workers cộng với external services. Đây là trường hợp khó của D1. Background jobs, webhook handlers, và data pipelines chạy ngoài Workers cần một proxy để reach D1. Package @tursodatabase/serverless của Turso hoạt động từ cả hai phía mà không cần thêm gì.
Vector search. Turso có kiểu vector native F32_BLOB và DiskANN indexing tích hợp trong libSQL — không cần extension. D1 không có hỗ trợ vector. Nếu bạn xây bất cứ thứ gì liên quan đến embeddings, lựa chọn ở đây rất rõ ràng.
Nếu SQLite edge không phải giải pháp phù hợp. Khi bạn cần row-level security, nhiều schema, hoặc Postgres đầy đủ tính năng, Supabase vs Firebase so sánh hai backend database phổ biến nhất theo giá cả và hiệu năng thực tế.
Kết luận
Chọn D1 nếu toàn bộ stack của bạn trên Cloudflare Workers. Giá cả hào phóng ở quy mô lớn, global read replication đã production-ready, và không cần quản lý infrastructure database riêng. Mô hình Workers binding đơn giản hơn bất kỳ cách nào dùng connection string. Thứ bạn từ bỏ là tính di động — D1 là sản phẩm của Cloudflare, không hơn không kém.
Chọn Turso nếu bạn cần tính di động, interactive transactions, hoặc database hoạt động đa runtime. Free tier dễ dùng hơn cho developer cá nhân (giới hạn theo tháng thay vì theo ngày), và open-source libSQL engine có nghĩa là wire protocol và định dạng file không thuộc về một nhà cung cấp duy nhất. Nếu Turso thay đổi mô hình kinh doanh ngày mai, data của bạn vẫn là SQLite hợp lệ.
Quyết định này mang tính kiến trúc hơn là kỹ thuật. Chọn D1 là chọn Cloudflare. Điều đó ổn nếu bạn đã cam kết — D1 là một sản phẩm thực sự tốt. Nếu không, Turso là thứ vẫn hoạt động khi bạn chuyển đi.