Neon vs Turso: Serverless Postgres so với SQLite (2026)
Neon thắng cho team Postgres và Vercel preview environments. Turso thắng cho workload đọc nhiều — nhưng embedded replicas không chạy trên Cloudflare Workers.
Bởi Ethan
2.226 từ · 12 phút đọc
Nếu bạn đang xây dựng trên Postgres và cần preview database theo từng branch, hoặc không muốn đau đầu với connection pooling, hãy dùng Neon. Nếu app của bạn thiên về đọc nhiều hơn viết và có thể sống chung với SQLite semantics, Turso đáng thử — với một ngoại lệ quan trọng: embedded replicas không hoạt động trên Cloudflare Workers. Cả hai đều mang nhãn “serverless”; nhưng ngoài cái tên đó ra, chúng khác nhau ở hầu hết mọi thứ.
Bài này dành cho ai
Dành cho developer đang chọn serverless database cho dự án mới, hoặc đang chuyển từ Postgres hay SQLite managed hosting truyền thống. Nếu bạn đã có quan điểm rõ ràng về Postgres so với SQLite, câu trả lời của bạn có lẽ đã sẵn trong đầu.
Chúng tôi đã thử nghiệm gì
Bài viết dựa trên tài liệu công khai, trang pricing, và changelog chính thức — không phải benchmark được kiểm soát. Chúng tôi có chạy query thực tế lên cả hai dịch vụ trong một project thử nghiệm, nhưng không có con số latency đối đầu nào vượt qua bước kiểm tra thực tế (xem phần Lưu ý). Tất cả dữ liệu giá là từ tháng 6 năm 2026; cả hai dịch vụ thay đổi giá thường xuyên.
Kết quả
Sự khác biệt cốt lõi
Neon là managed Postgres — cụ thể là dự án Neon open-source, tách biệt storage khỏi compute, cho phép copy-on-write branching, và bổ sung pricing model serverless lên trên. SQL của bạn là PostgreSQL chuẩn. ORM của bạn chạy được ngay. Driver pg của bạn chạy được ngay.
Turso là managed service xây dựng trên libSQL — một fork của SQLite bổ sung network access, replication, và một số extension. SQL của bạn là SQLite SQL — về cơ bản gần với ANSI SQL, nhưng có đủ điểm khác biệt để gây vấn đề nếu bạn không để ý (xem phần “Những bẫy của SQLite” bên dưới).
Nếu codebase của bạn đang dùng Postgres, câu hỏi “liệu nó có chạy được với Neon không?” gần như không cần đặt ra. Với Turso thì có.
Branching
Branching là tính năng nổi bật nhất của Neon — và là điểm mà nó không có đối thủ thực sự. Tạo một branch là thao tác copy-on-write tức thì — Neon không sao chép dữ liệu; nó tạo ra một con trỏ mới vào cùng storage. Bạn có thể tạo database branch cho mỗi PR trong CI pipeline mà về cơ bản không tốn thêm chi phí hay thời gian.
# Neon CLI — tạo branch cho một PR
neonctl branches create --project-id <id> --name preview/pr-42 --parent main
Turso không có tính năng tương đương. Nó có read replicas và embedded replicas, nhưng đó là replication — không phải copy-on-write branches của schema và dữ liệu.
Nếu branching quan trọng với workflow của bạn, phần này đã kết thúc cuộc so sánh. Nếu bạn cũng đang cân nhắc Supabase như một lựa chọn Postgres managed, Neon vs Supabase so sánh trực tiếp hai dịch vụ đó.
Connection pooling
Neon đi kèm PgBouncer trong mỗi project — bật bằng cách thêm ?pgbouncer=true vào connection string. Nó xử lý được tới 10,000 client. Trong môi trường serverless (Vercel Edge Functions, Next.js API routes), nơi mỗi lần gọi function mở một connection mới, đây là thứ cứu bạn khỏi lỗi “too many connections” — thứ giết chết hầu hết các setup Postgres serverless đơn giản.
Turso được thiết kế theo kiểu mỗi HTTP request là một connection. SQLite không có vấn đề cạn kiệt connection như Postgres.
Scale to zero
Cả hai dịch vụ đều scale to zero. Compute của Neon sẽ tạm dừng sau 5 phút không hoạt động ở free tier; cold start mất vài trăm millisecond. Ở paid tier, bạn có thể tắt hoàn toàn tính năng tự suspend hoặc điều chỉnh thời gian chờ.
Database của Turso cũng ngủ sau khi không có hoạt động. Cold start tương đương.
Embedded replicas — và lý do chúng không hoạt động trên Cloudflare Workers
Tính năng thú vị nhất của Turso là embedded replicas: app của bạn giữ một file SQLite local và tự đồng bộ với remote primary. Reads đọc thẳng từ file local (không có network round-trip); writes đi qua HTTP API lên primary rồi sync ngược lại. Với các process chạy lâu dài — một Node.js server chạy hàng giờ, Electron app, background job — đây là lợi thế thực sự.
import { createClient } from "@libsql/client";
const client = createClient({
url: "file:local.db",
syncUrl: process.env.TURSO_DATABASE_URL,
authToken: process.env.TURSO_AUTH_TOKEN,
syncInterval: 60, // giây
});
await client.sync(); // kéo dữ liệu mới nhất từ primary
const result = await client.execute("SELECT * FROM products WHERE active = 1");
Vấn đề là: embedded replicas cần filesystem có quyền ghi. Cloudflare Workers không cung cấp điều đó. Nếu bạn deploy lên Workers, bạn phải dùng @libsql/client/web — chế độ HTTP-only — nghĩa là mọi read đều phải đi qua network. Lợi thế về proximity với edge biến mất hoàn toàn. Tài liệu của Turso thừa nhận điều này; đây không phải bug, nhưng là điểm quan trọng cần nắm rõ trước khi cam kết với kiến trúc này. Nếu Cloudflare Workers là môi trường deploy của bạn, Turso vs D1 so sánh Turso với lựa chọn SQLite native của Cloudflare.
Neon trên Cloudflare Workers là một đánh đổi khác. Neon khuyến nghị dùng Hyperdrive (connection proxy của Cloudflare) cùng với pg ≥ 8.16.3 để đạt latency chấp nhận được. Bạn vẫn dùng Postgres qua TCP, nhưng Hyperdrive cache phần thiết lập connection và pool ngay tại edge.
// Neon trên Cloudflare Workers qua Hyperdrive
import { Pool } from "pg";
export default {
async fetch(request: Request, env: { HYPERDRIVE: Hyperdrive }) {
const pool = new Pool({ connectionString: env.HYPERDRIVE.connectionString });
const { rows } = await pool.query("SELECT now()");
await pool.end();
return Response.json(rows[0]);
},
};
Cả hai lựa chọn đều không phải zero-latency. Neon thêm một TCP round-trip qua Hyperdrive. Turso ở web mode thêm một HTTP round-trip đến replica gần nhất. Nếu edge latency thực sự là yếu tố quyết định, bạn cần một giải pháp database khác hoàn toàn — D1 hoặc on-device store. Edge database tradeoffs: khi latency là lời nói dối phân tích toàn cảnh các lựa chọn edge database và khi nào Neon, Turso, D1, hay Postgres truyền thống phù hợp hơn.
Pricing
| Tier | Neon | Turso |
|---|---|---|
| Free | 100 CU-hrs/tháng, 0.5 GB storage, 10 branch, bắt buộc scale-to-zero sau 5 phút | 100 database, 500M row reads/tháng, 10M writes/tháng, 5 GB tổng |
| ~$25/tháng | Launch: $0.106/CU-hr + $0.35/GB-tháng, không có phí tối thiểu | Scaler: $24.92/tháng cố định — 24 GB storage, 100B row reads, 100M writes |
Một số điểm đáng chú ý.
Free tier của Neon bị giới hạn bởi compute, không phải dữ liệu. 100 compute-unit-hours nghe có vẻ rộng rãi — cho đến khi bạn hiểu đơn vị này. Đại khái: 1 CU ≈ 4 GB RAM; kích thước compute nhỏ nhất là 0.25 CU (1 GB RAM). Compute đang hoạt động sẽ tiêu thụ compute-unit-hours tỉ lệ với kích thước bạn cấp phát. Một dự án hobby với vài giờ traffic mỗi ngày ở mức compute tối thiểu thì vừa đủ. Một project chạy liên tục ở 1 CU sẽ chạm ngưỡng rất nhanh.
Free tier của Turso được thiết kế cho multi-tenant app. 100 database riêng biệt đủ để mỗi user trong một SaaS nhỏ có SQLite database riêng. Đây là use case thực tế: database per-user là design pattern của Turso, khả thi nhờ footprint nhẹ của libSQL. Neon không có mô hình tương đương ở mức giá này — các branch dùng chung storage và compute, và bạn trả tiền theo project.
Tier $25 của Neon không có mức tối thiểu. Bạn trả theo mức sử dụng thực tế. Một project scale to zero và chỉ dùng 10 giờ compute mỗi tháng chỉ tốn $1.06 tiền compute. Turso Scaler là $24.92 cố định dù bạn dùng ít đến đâu.
Bảng so sánh tính năng
| Tính năng | Neon | Turso |
|---|---|---|
| SQL dialect | PostgreSQL | SQLite / libSQL |
| Copy-on-write branching | Có (tức thì) | Không |
| Connection pooling | PgBouncer tích hợp sẵn (10,000 client) | Không áp dụng (HTTP per request) |
| Scale to zero | Có (timeout có thể điều chỉnh) | Có |
| Embedded replicas | Không | Có (cần filesystem có quyền ghi) |
| Cloudflare Workers | Hyperdrive + pg ≥ 8.16.3 | @libsql/client/web — HTTP only, không có embedded replicas |
| Dịch vụ xác thực | Neon Auth (beta) | Không có sẵn |
| Database trên free tier | 1 project, 10 branch | 100 database |
| Open source | Có (Neon) | Có (libSQL) |
Những bẫy của SQLite
Nếu đây là lần đầu bạn dùng SQLite trong production với Turso, những điều sau sẽ gây khó chịu:
1. Không ép kiểu theo mặc định. SQLite dùng “type affinity” — không phải ép kiểu cứng. Cột INTEGER chấp nhận text mà không báo lỗi, trừ khi bạn dùng STRICT tables. Hầu hết tutorial bỏ qua STRICT; bạn cần khai báo tường minh:
CREATE TABLE products (
id INTEGER NOT NULL,
price REAL NOT NULL,
sku TEXT NOT NULL
) STRICT;
2. ALTER TABLE bị giới hạn nghiêm trọng. Bạn không thể thay đổi kiểu của cột, đổi tên cột (trước SQLite 3.25.0), hoặc thêm constraint sau khi đã tạo. Schema evolution đòi hỏi viết lại bảng — các migration tool như Drizzle xử lý được việc này, nhưng nó gây bất ngờ cho team quen với ALTER COLUMN kiểu Postgres.
3. Chỉ một writer tại một thời điểm. libSQL bổ sung network access nhưng vẫn giữ mô hình single-writer của SQLite. Ở embedded replica mode, mọi write đều đi lên remote primary và xếp hàng tại đó. Dưới độ tương tranh write cao, bạn sẽ thấy latency tăng trước khi thấy lỗi.
4. Foreign keys tắt theo mặc định. Bạn phải chạy PRAGMA foreign_keys = ON; trên mỗi connection — hoặc cấu hình ở cấp độ client — nếu không các ràng buộc referential integrity sẽ không có tác dụng gì.
5. Không có JSONB. SQLite lưu JSON dưới dạng text. Các hàm json_* hoạt động được cho việc trích xuất và truy vấn path, nhưng không có kiểu binary JSON và không hỗ trợ index-on-path tương đương GIN indexes của jsonb trong Postgres.
6. Ép kiểu ngầm. Trong nhiều ngữ cảnh, '123' = 123 trả về true. Điều này che giấu các lỗi so sánh mà Postgres sẽ phát hiện ngay lúc chạy query.
Từng điểm một, không cái nào là vấn đề không thể giải quyết. Gộp lại, chúng tạo ra chi phí migration đáng kể nếu codebase của bạn phụ thuộc vào các tính năng đặc thù của Postgres — arrays, enums, JSONB, full-text search vectors, hay window functions với syntax riêng của Postgres.
Kết luận
Chọn Neon nếu:
- Bạn đang dùng Postgres và muốn tiếp tục dùng Postgres.
- Bạn dùng Vercel hoặc nền tảng tương tự và muốn preview database theo từng PR.
- Bạn cần connection pooling đáng tin cậy mà không phải tự vận hành PgBouncer.
- Team của bạn dùng các tính năng đặc thù của Postgres (JSONB, arrays,
pg_trgm, full-text, enums).
Chọn Turso nếu:
- App của bạn thiên về đọc và tỷ lệ read/write nghiêng rõ về phía read.
- Bạn cần nhiều database nhỏ, độc lập với chi phí thấp — database per-user, SaaS multi-tenant.
- Bạn deploy lên Node.js, Bun, hoặc Deno (không phải Cloudflare Workers) và muốn dùng embedded replicas.
- Bạn chấp nhận được các giới hạn của SQLite và schema của bạn dễ migrate.
Đừng chọn Turso cho Cloudflare Workers nếu bạn trông đợi embedded replicas. Bạn sẽ chỉ có HTTP-only mode và một network round-trip. Nếu điều đó chấp nhận được, không vấn đề — nhưng hãy benchmark trước.
Lưu ý
Không có benchmark latency đã được xác minh. Chúng tôi đã tìm kiếm benchmark đối đầu đáng tin cậy và không tìm thấy cái nào vượt qua kiểm tra thực tế. So sánh được trích dẫn nhiều nhất dựa trên dữ liệu thô mà chúng tôi không thể tự xác minh. Nếu latency là yếu tố quyết định, hãy tự chạy test trên workload và môi trường deploy của chính mình.
Giá thay đổi nhanh. Cả hai dịch vụ đều đã điều chỉnh giá trong 12 tháng qua. Các con số trên là từ tháng 6 năm 2026. Hãy kiểm tra trang pricing hiện tại trước khi cam kết với một tier.
Không có affiliate link. Tại thời điểm viết bài, cả Neon lẫn Turso đều không có chương trình affiliate được công bố công khai. Bài viết này không có affiliate link.