Turso: A Rust Engineer's First Look at the Edge Database Written in Rust
$ turso db create iot-fleet-primary
# wait, the engine is written in Rust?I was knee-deep in edge database research when I stumbled on Turso. I almost scrolled past it. I’m glad I didn’t.
How I Got Here
I wasn’t looking for Turso specifically. I was researching edge databases — trying to figure out whether there was something better suited for the kind of lightweight, low-latency data layer I keep needing in my IoT and systems projects. Most of what I found was either “just use Postgres with a connection pooler” or “have you tried PlanetScale?” — neither of which scratched the itch.
Then Turso showed up.
The thing that made me stop scrolling wasn’t the marketing. It was two words buried in the docs: written in Rust. Not “has a Rust client.” Not “Rust SDK available.” The new Turso Database engine — their ground-up rewrite — is built in Rust. As someone who lives in Rust daily, that immediately changed the conversation for me.
My current go-to for embedded storage in Rust is plain rusqlite. It works. It’s solid. I’ve shipped production systems with it. But it has edges — pun intended — and I’ve always felt like I was one distributed requirement away from outgrowing it. Turso looked like it might be the answer I didn’t know I was looking for. So I gave it a proper first look.
This isn’t a polished “here’s everything Turso can do” guide. This is me, a Rust-first systems engineer, seeing Turso for the first time and writing down exactly what I find — warts and all.
First, Let’s Clear Up the Confusion: libSQL vs. Turso Database
Before you do anything with Turso, you need to understand one thing that tripped me up early: Turso and libSQL are two different things, and most articles conflate them.
libSQL is an open-source fork of SQLite. The Turso team built it because SQLite is open-source but notoriously closed to outside contributions. libSQL adds things SQLite doesn’t have: embedded replicas, network access over HTTP and WebSockets, native vector search, and better ALTER TABLE support. It’s fully backwards-compatible with SQLite. Think of it as “SQLite, but the community can actually improve it.”
Turso Database is something else entirely. It’s not a fork. It’s a full rewrite of SQLite from scratch — in Rust — designed to go beyond what any SQLite fork can offer. We’re talking concurrent writes, bi-directional sync, and offline support. It’s the future direction. As of this writing, it’s still in beta.
The relationship looks like this:
SQLite (upstream, closed contribution)
└── libSQL (open fork, production-ready today)
└── Turso Cloud (managed platform, runs on libSQL now, Turso DB engine coming)
Turso Database (ground-up Rust rewrite, beta — the future)Most tutorials you’ll find are about libSQL + Turso Cloud. The new Rust-native Turso Database engine is a separate beast that’s still maturing. For this review, I’m working with the production-ready path: libSQL + Turso Cloud + the Rust client. But knowing the distinction matters — especially if you’re reading docs and things don’t add up.
What Turso Actually Is (And Why It’s Interesting)
At its core, Turso is an edge-hosted SQLite-compatible database. Here’s what that means in practice:
- Your primary database lives in a home region (you pick it)
- Turso replicates it automatically to edge locations around the world
- Reads hit the nearest edge replica — we’re talking sub-10ms globally
- Writes go to the primary and propagate to replicas with 1–50ms lag
- You can also run embedded replicas — a local SQLite file on your machine or server that stays synced with the remote primary, giving you microsecond read latency for local reads
That last point is what makes Turso genuinely interesting for systems work. An embedded replica means your application reads from a local file — no network hop, no latency — while still having a synchronized remote primary for durability and multi-device access. That’s a different architectural primitive from anything I was using with rusqlite.
The free tier is generous: 5GB storage, 100 databases, 500 million row reads per month. For a side project or IoT prototype, you’re not paying anything.
Setting It Up: Faster Than I Expected
I’ll be honest — I expected Turso’s setup to be the typical “10 steps, create an account, configure a YAML file, pray” experience. It wasn’t.
Step 1: Install the CLI
# macOS / Linux
curl -sSfL https://get.tur.so/install.sh | bash
# Or install from source (obviously I did this)
cargo install tursoStep 2: Login and create a database
turso auth login
turso db create my-first-turso-dbThat’s it. You have a database. The CLI spits out a URL and you’re done. I timed it: under 90 seconds from zero to a live, globally-replicated database.
Step 3: Grab your auth token
turso db tokens create my-first-turso-dbKeep this token. You’ll need it for your client.
Connecting from Rust
This is the part I was most curious about. How does the Rust integration actually feel?
The official client is libsql on crates.io. Add it to your Cargo.toml:
[dependencies]
libsql = "0.6"
tokio = { version = "1", features = ["full"] }Remote connection (Turso Cloud)
use libsql::{Builder, params};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = Builder::new_remote(
"libsql://your-db.turso.io".to_string(),
"your-auth-token".to_string(),
)
.build()
.await?;
let conn = db.connect()?;
conn.execute(
"CREATE TABLE IF NOT EXISTS sensors (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
value REAL NOT NULL,
ts INTEGER NOT NULL
)",
(),
)
.await?;
conn.execute(
"INSERT INTO sensors (name, value, ts) VALUES (?1, ?2, ?3)",
params!["temperature", 23.4_f64, 1714000000_i64],
)
.await?;
let mut rows = conn
.query("SELECT * FROM sensors", ())
.await?;
while let Some(row) = rows.next().await? {
let name: String = row.get(1)?;
let value: f64 = row.get(2)?;
println!("{name}: {value}");
}
Ok(())
}Familiar. Clean. If you’ve used rusqlite, the mental model maps almost 1:1 — just async. The params! macro feels right at home, and the error handling is idiomatic Rust.
Embedded replica (the interesting part)
use libsql::Builder;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = Builder::new_remote_replica(
"/tmp/local-replica.db", // local SQLite file
"libsql://your-db.turso.io".to_string(),
"your-auth-token".to_string(),
)
.build()
.await?;
// Sync from remote before reading
db.sync().await?;
let conn = db.connect()?;
// This read hits the local file — microsecond latency
let mut rows = conn.query("SELECT * FROM sensors", ()).await?;
while let Some(row) = rows.next().await? {
println!("{:?}", row.get::<String>(1)?);
}
Ok(())
}The db.sync() call pulls latest changes from the remote primary into your local file. Reads after that are local. Writes still go remote. It’s a simple mental model once you see it — almost like a git pull before you start working.
The rusqlite Comparison I Had to Make
I’ve been using rusqlite for embedded SQLite in Rust for years. It’s synchronous, battle-tested, and dead simple. So I ran a quick, unscientific comparison on my machine — just to get a feel.
Setup: 10,000 sequential inserts, then 10,000 point reads. Single table, simple schema. My local machine, Indonesia, Turso primary region: Singapore (ap-southeast).
| Operation | rusqlite (local) | Turso remote | Turso embedded replica |
|---|---|---|---|
| 10k inserts | ~45ms | ~12s | ~12s (writes go remote) |
| 10k reads | ~8ms | ~3.2s | ~11ms |
The takeaway: For writes, Turso is not competing with local SQLite — and it doesn’t claim to. Writes have to make a network round-trip, and that’s the trade-off you’re accepting. For reads with an embedded replica, the story is much closer. My 11ms vs rusqlite’s 8ms is a gap I can live with for most workloads, and that gap disappears entirely when the replica is properly warmed.
What rusqlite can’t do is give me that same data on another machine, or at an edge location, or synced across a fleet of IoT devices. That’s where the comparison stops making sense — they’re solving different problems.
What Genuinely Surprised Me
1. The database-per-tenant pricing model
Turso’s pricing is unusual: at $4.99/month (Developer plan), you get unlimited databases. That unlocks a pattern called database-per-tenant — give every user or device their own isolated SQLite database. For an IoT device fleet, this is potentially huge. Each device gets its own DB, complete isolation, no shared-table contention. Competitors charge per database, making this approach economically absurd anywhere else.
2. The CLI is genuinely pleasant
turso db list, turso db show, turso db inspect — these are the kinds of commands that feel like someone actually uses the tool they built. The CLI has personality without being annoying.
3. Native vector search
I wasn’t expecting this. libSQL has built-in vector search, which means you can store embeddings alongside your relational data without a separate vector store. For someone who’s been thinking about edge-deployed ML inference (pairing this with a Burn-generated embedding model, for instance), this is a quietly significant feature.
4. The Rust rewrite story
The new Turso Database engine — the one still in beta — being written from scratch in Rust is philosophically aligned with everything I believe about systems software. Concurrent writes, bi-directional sync, offline support. These aren’t features you can bolt onto a C codebase fork. They had to start fresh. I respect that call, even if it means I have to wait a bit longer for production readiness.
Where I’d Be Cautious
No honest review skips the rough edges.
Write-heavy workloads: If your system is write-heavy, Turso will feel slow compared to local SQLite. Every write goes to the primary over the network. That’s an architectural reality, not a bug — but it matters.
Beta status of the new engine: The full Turso Database (the Rust rewrite) is still in beta. The libSQL-based platform is production-ready, but if you’re excited about the concurrent-write story, you’re not there yet.
No built-in query profiler: EXPLAIN QUERY PLAN works locally, but Turso has no dashboard-level query performance tooling. You’re on your own for optimization visibility.
The libSQL vs. Turso naming confusion: I mentioned this at the top, but it’s worth repeating — the docs are improving but the split identity between the two projects still creates friction when you’re reading community resources.
So, Could It Replace rusqlite for Me?
Here’s my honest answer after this first look: not entirely, but yes for some things.
For pure local, offline, single-process storage where I need maximum write throughput — rusqlite stays. It’s synchronous, zero-overhead, and nothing I’ve seen matches it for that specific use case.
But for anything that needs to be accessed from multiple places — a config store shared across a device fleet, a telemetry sink that I want to query remotely, an IoT backend that benefits from edge-proximity reads — Turso is now my first consideration. The embedded replica model fits the way I think about systems: keep data local for performance, sync for durability and accessibility.
And I’ll be watching the new Turso Database engine closely. A Rust-native, concurrent-write, offline-capable SQLite replacement built by people who clearly care about the right things? That’s not something I can ignore.
Getting Started Yourself
If you want to try it:
- Install the Turso CLI
- Add
libsql = "0.6"to yourCargo.toml - Create a database:
turso db create my-db - Start with a remote connection, then graduate to an embedded replica once you understand the sync model
The official Rust SDK docs are solid. The quickstart actually works, which is more than I can say for a lot of database clients.
Wrapping Up
I came to Turso while researching edge databases, not really expecting to find something that fit my world. What I found was a genuinely well-designed product with a clear architectural philosophy, a Rust-native future that aligns with how I think about systems, and pricing that makes unusual patterns (like database-per-device for IoT) actually viable.
It’s not a drop-in replacement for rusqlite. It’s not trying to be. It’s something new — a local-first, edge-aware, SQLite-compatible database layer — and it’s interesting enough that I’m going to keep using it and almost certainly write a follow-up once I’ve put it through its paces in a real IoT pipeline.
Stay tuned for that.
Have you tried Turso in a Rust project? I’d love to hear what you’re building with it — reach out at qcynaut@gmail.com or find me on GitHub @qcynaut.