SQLite Concurrent Writes Are Here: Early Preview on Turso Cloud

Concurrent Writes on the Turso Cloud: SQLite without its limits

Cover image for SQLite Concurrent Writes Are Here: Early Preview on Turso Cloud

After a successful private beta, today we are happy to announce the early preview of concurrent writes on the Turso Cloud. The early access is open to everybody.

“We believe Turso’s SQLite-compatible, embedded-first architecture is a natural fit for the next generation of Devolutions products. Our contribution of first-class .NET support reflects that commitment: we’re not merely evaluating Turso—we’re investing in the ecosystem we expect to build on.” - Marc-André Moreau, CTO, Devolutions

What concurrent writes do on Turso Cloud: Turso Cloud databases can run transactions with BEGIN CONCURRENT, which allows multiple writers to proceed in parallel instead of serializing behind one write lock. Conflicts are detected at commit time at row granularity, so transactions touching different rows commit without interference. Available in early preview as of August 3, 2026.

A note on names, since three things share one: Turso is the database engine, a ground-up Rust rewrite of SQLite. Turso Cloud is the hosted platform. Turso, Inc is also the company. This post is about the engine's concurrency model arriving on the hosted platform.

#Why SQLite only allows one writer

SQLite in WAL mode lets many readers run alongside a single writer. Serializing writes was a sensible simplification for the hardware SQLite was designed against, and it holds up well through prototyping.

What actually makes SQLite so dependable and so easy to deploy is everything around that choice: a single file, no server process to run, no network hop, and one of the most rigorously tested codebases in software. Turso keeps all of it, and improves in key areas: concurrency through MVCC, chief among them.

The trouble shows up even at low throughput. A second writer arriving mid-transaction gets this:

Error: database is locked (SQLITE_BUSY)

Applications work around it by wrapping every write in a backoff-and-retry loop or serialization queue, and throughput stays capped at whatever one writer can push.

#How Turso handles concurrent writes

SQLite has an experimental BEGIN CONCURRENT branch that has never been merged into mainline. It defers the write lock until commit, so several write transactions can run optimistically in parallel. Conflict detection on that branch happens at the page level, so two transactions updating unrelated rows that happen to share a B-tree page still collide.

Turso borrows the syntax and changes the mechanism. Underneath BEGIN CONCURRENT sits a multi-version concurrency control (MVCC) engine. MVCC keeps several versions of a row at once, tracked in an in-memory index, so a writer produces a new version of a row instead of taking a lock that everyone else waits behind. Readers continue seeing the version that was current when their transaction started.

The specific approach follows Hekaton, the memory-optimized engine Microsoft built into SQL Server and published at SIGMOD 2013, which laid out the latch-free, optimistic MVCC scheme that most modern in-memory engines have drawn on since (paper). Turso adapts it to SQLite's B-tree storage, where conflict detection happens at the row level, so unrelated rows sharing a page no longer produce false conflicts.

SQLite (default)SQLite BEGIN CONCURRENT branchTurso
Writers at a timeOneSeveral, optimisticSeveral, optimistic
When locking happensTransaction startCommitCommit
Conflict granularityWhole databasePageRow
Retry requiredOn SQLITE_BUSY at startOn page conflict at commitOn row conflict at commit
AvailabilityMainlineExperimental branch onlyTurso engine, and now Turso Cloud

#Do I still need retry logic?

Yes, but less of it.

The lock contention at transaction start is gone. What remains is a genuine conflict: two transactions wrote the same rows, and the second one to commit gets a conflict error, rolls back, and retries. Workloads spread across distinct rows rarely hit this path. Workloads that hammer a single hot row will hit it often, but that's just life under ACID.

"Agents have cut app development from weeks to hours, making Turso more relevant than ever. Concurrent writes and scaling fears always kept me away from SQLite, Turso Cloud removed that ceiling. Plus, it costs me 10x less than Neon, my previous solution." - Tejas Kumar, Influencer, International Keynote Speaker and Podcast host @TejasKumar_

#Using Concurrent Writes

During the early preview phase, you have to explicitly enable the feature in your dashboard. You can do this on the “Settings” -> “General” tab in the Turso dashboard:

Once concurrent writes is enabled in your account, you must create a tursodb database, instead of the default of SQLite.

On the CLI:

turso db create --tursodb <name>

On the dashboard UI:

Once a Turso database is created, you can issue concurrent writes by creating your transactions with BEGIN CONCURRENT instead of BEGIN

#Using Concurrent Writes in TypeScript

import { connect } from "@tursodatabase/serverless";

const conn = connect({
  url: process.env.TURSO_DATABASE_URL,
  authToken: process.env.TURSO_AUTH_TOKEN,
});

// Transaction API: the .concurrent variant runs BEGIN CONCURRENT .. COMMIT
const insertUser = conn.transactionAsync(async (tx, name) => {
  await tx.run("INSERT INTO users (name) VALUES (?)", [name]);
});
await insertUser.concurrent("Alice");

// Explicit
await conn.exec("BEGIN CONCURRENT");
await conn.run("INSERT INTO users (name) VALUES (?)", ["Bob"]);
await conn.exec("COMMIT");
await conn.close();

#Using Concurrent Writes in Rust

use turso_serverless::{Builder, TransactionBehavior};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let db = Builder::new_remote(std::env::var("TURSO_DATABASE_URL")?)
        .with_auth_token(std::env::var("TURSO_AUTH_TOKEN")?)
        .build()
        .await?;
    let mut conn = db.connect()?;

    // Connection default: every transaction becomes BEGIN CONCURRENT
    conn.set_transaction_behavior(TransactionBehavior::Concurrent);
    let tx = conn.transaction().await?;
    tx.execute("INSERT INTO users (name) VALUES (?)", ["Alice"]).await?;
    tx.commit().await?;

    // Per-transaction
    let tx = conn.transaction_with_behavior(TransactionBehavior::Concurrent).await?;
    tx.execute("INSERT INTO users (name) VALUES (?)", ["Bob"]).await?;
    tx.commit().await?;

    Ok(())
}

#Using Concurrent Writes in Python

import turso_serverless
import os

# Implicit: every implicit BEGIN becomes BEGIN CONCURRENT
conn = turso_serverless.connect(
    os.environ["TURSO_DATABASE_URL"],
    auth_token=os.environ["TURSO_AUTH_TOKEN"],
    isolation_level="CONCURRENT",
)
conn.execute("INSERT INTO users (name) VALUES (?)", ("Alice",))
conn.commit()

# Explicit
conn.execute("BEGIN CONCURRENT")
conn.execute("INSERT INTO users (name) VALUES (?)", ("Bob",))
conn.commit()
conn.close()

#Conclusion

Last year, we went all-in on an ambitious project: rewriting SQLite from scratch. We did that because despite the growth of our Cloud, we kept hearing users complaining that for all its marvels, lack of concurrent writes were a major limitation to the applications developers and their agents were trying to write, to benefit from the unmatched price/performance of the Turso Cloud. Turso, the Open Source engine, has supported concurrent writes with MVCC for a couple of months now. And we are glad to take the next step: now you can run it in the Cloud!

Sign up today for the Turso Cloud, and create your tursodb databases!