Skip to main content
Turso’s architecture closely follows SQLite’s but departs in one fundamental way: all I/O is asynchronous. This enables io_uring on Linux, cross-platform non-blocking I/O, and cloud integration (backup, replication) without blocking the execution engine.

Component pipeline

Every SQL statement travels through the following pipeline before returning rows to the caller:
SQL text


┌─────────────────────┐
│       Parser        │  parser/src/parser.rs
│  (lexer → AST)      │  11k LOC recursive descent
└────────┬────────────┘
         │  Cmd::Stmt (AST)

┌─────────────────────┐
│   Code Generator /  │  core/translate/
│    Translator       │  AST → bytecode + optimizer
└────────┬────────────┘
         │  Program (bytecode)

┌─────────────────────┐
│   VDBE Bytecode     │  core/vdbe/execute.rs
│   Virtual Machine   │  12k LOC interpreter
└────────┬────────────┘
         │  page reads/writes

┌─────────────────────┐
│    Storage Layer    │  core/storage/
│  (B-tree + Pager)   │  btree.rs, pager.rs
└────────┬────────────┘
         │  async I/O ops

┌─────────────────────┐
│     I/O Backend     │  core/io/
│  (io_uring / sync)  │  IOResult, Completion
└─────────────────────┘

Sequence of operations

The following sequence diagram (from the Turso manual) shows a query from the CLI shell through to the VDBE:
cli/main ──open_file──► Database
         ◄── Connection ─

cli/main ──query(sql)──► Connection

                         Connection ──next()──► Parser
                              │                (parser/src/parser.rs)
                              │         ◄── Cmd::Stmt (AST)

                         Connection ──translate(stmt)──► translate/mod
                              │                   ◄── Program (bytecode)

cli/main ◄── Ok(Rows { Statement }) ──

cli/main ──step()──► Statement

                     Statement ──step()──► Program
                                    (executes bytecode, see sqlite.org/opcode.html)
                          │         ◄── StepResult
cli/main ◄── StepResult ──
The key interfaces are:
  • sqlite3_prepare() equivalent — translates SQL to a bytecode Program (a prepared statement).
  • sqlite3_step() equivalent — advances execution of the Program one row at a time.

Source code map

ComponentLocationNotes
SQL parserparser/src/parser.rs11k LOC recursive descent, fork of lemon-rs
Lexerparser/src/lexer.rsKeyword recognition, token types
AST typesparser/src/ast.rsAll statement and expression nodes
Translator / code generatorcore/translate/AST → VDBE bytecode
Query optimizercore/translate/optimizer/System R-style DP join ordering
VDBE instruction setcore/vdbe/insn.rsAll opcode definitions
VDBE execution enginecore/vdbe/execute.rs12k LOC bytecode interpreter
B-tree storagecore/storage/btree.rs10k LOC, SQLite-compatible format
Pagercore/storage/pager.rsPage management, transactions, dirty tracking
Write-ahead logcore/storage/wal.rsWAL frames, checkpointing
Buffer poolcore/storage/buffer_pool.rsIn-memory page cache
I/O abstractioncore/io/Completion, CompletionGroup, platform backends
MVCC enginecore/mvcc/Experimental multi-version concurrency

How Turso differs from SQLite

The primary architectural difference is the asynchronous I/O model. SQLite performs all I/O synchronously: a read blocks the calling thread until the data is available. Turso instead models every I/O operation as a Completion object. The VDBE returns StepResult::IO when it needs to wait for a completion, and the caller re-enters step() once the I/O is done. This design:
  • Enables io_uring on Linux for high-throughput, low-latency storage access.
  • Allows cloud-backed storage (backup, sync) without threading.
  • Forces all code that touches storage to handle the “not done yet” case explicitly — which catches latent concurrency bugs.
Turso does not use Rust async/await. Instead it implements cooperative yielding with explicit state machines and the IOResult<T> enum. See Async I/O for details.

High-level interface compatibility

Turso exposes the same high-level API as SQLite:
  • The same SQL query language (aiming for full compatibility).
  • The sqlite3_prepare() function for compiling SQL to programs.
  • The sqlite3_step() function for executing programs row by row.
  • The SQLite C API (via bindings) for drop-in compatibility.

Explore individual components

Parser

Recursive descent SQL parser and AST.

Query optimizer

System R-style join ordering and index selection.

Virtual machine

VDBE bytecode interpreter and opcode reference.

Storage

B-tree, WAL, pager, and SQLite file format.

Async I/O

IOResult, Completion, state machines, io_uring.

MVCC

Experimental multi-version concurrency control.

Build docs developers (and LLMs) love