> ## Documentation Index
> Fetch the complete documentation index at: https://docs.turso.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Reference

> Rust Reference for Turso

Turso offers two Rust crates:

|                       | `turso`                         | `libsql`                                                  |
| --------------------- | ------------------------------- | --------------------------------------------------------- |
| **Use case**          | Local / embedded database, sync | Remote access, existing libSQL codebases                  |
| **Engine**            | Turso Database (rewrite)        | libSQL (SQLite fork)                                      |
| **Concurrent writes** | Yes (MVCC)                      | Not supported                                             |
| **Sync**              | push/pull (local-first)         | Embedded Replicas (writes go to cloud primary)            |
| **C compiler**        | Not required                    | Required for `core`, `replication`, `encryption` features |

**Starting a new project?** Use `turso` for local/embedded use or sync. Use `libsql` with the `remote` feature for over-the-wire access (no C compiler needed).

## turso

For local and embedded use. Built on the Turso Database engine with concurrent writes (MVCC) and async I/O.

### Installing

```bash theme={null}
cargo add turso tokio --features tokio/full
```

### Connecting

```rust theme={null}
use turso::Builder;

let db = Builder::new_local("app.db").build().await?;
let conn = db.connect()?;
```

In-memory databases are also supported:

```rust theme={null}
let db = Builder::new_local(":memory:").build().await?;
```

### Querying

```rust theme={null}
conn.execute(
    "CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL
    )",
    (),
).await?;

conn.execute("INSERT INTO users (name) VALUES (?)", ("Alice",)).await?;

let mut rows = conn.query("SELECT * FROM users", ()).await?;
while let Some(row) = rows.next().await? {
    let id: i64 = row.get(0)?;
    let name: String = row.get(1)?;
    println!("User: {} {}", id, name);
}
```

### Prepared Statements

```rust theme={null}
let mut stmt = conn.prepare("SELECT * FROM users WHERE id = ?1").await?;
let mut rows = stmt.query([42]).await?;
```

### Transactions

```rust theme={null}
let tx = conn.transaction().await?;

tx.execute("INSERT INTO users (name) VALUES (?1)", ["Alice"]).await?;
tx.execute("INSERT INTO users (name) VALUES (?1)", ["Bob"]).await?;

tx.commit().await?;
```

### Encryption

Encrypt local databases at rest:

```rust theme={null}
use turso::{Builder, EncryptionOpts};

let db = Builder::new_local("encrypted.db")
    .experimental_encryption(true)
    .with_encryption(EncryptionOpts {
        cipher: "aegis256".to_string(),
        hexkey: "b1bbfda4f589dc9daaf004fe21111e00dc00c98237102f5c7002a5669fc76327".to_string(),
    })
    .build()
    .await?;
```

Supported ciphers: `aegis256`, `aegis256x2`, `aegis128l`, `aegis128x2`, `aegis128x4`, `aes256gcm`, `aes128gcm`.

Encrypted databases cannot be read as standard SQLite databases — you must use the Turso Database engine to open them.

<Info>
  Turso Cloud databases can also be encrypted with bring-your-own-key — [learn more](/cloud/encryption).
</Info>

### Sync (Push and Pull)

For local database with cloud sync. All reads and writes happen locally; use `push()` to send changes to the cloud and `pull()` to fetch remote changes.

Enable the `sync` feature:

```bash theme={null}
cargo add turso --features sync
```

```rust theme={null}
use turso::sync::Builder;

let db = Builder::new_remote("app.db")
    .with_remote_url(&std::env::var("TURSO_DATABASE_URL")?)
    .with_auth_token(&std::env::var("TURSO_AUTH_TOKEN")?)
    .bootstrap_if_empty(true)  // Download schema on first sync (default)
    .build()
    .await?;

let conn = db.connect().await?;
```

On the first run, the local database is automatically bootstrapped from the remote. See [Turso Sync](/sync/usage) for full details.

#### Push and Pull

```rust theme={null}
// Push local writes to Turso Cloud
db.push().await?;

// Pull remote changes (returns true if changes were applied)
let changed = db.pull().await?;
```

#### Checkpoint

Compact the local WAL to bound disk usage while preserving sync state:

```rust theme={null}
db.checkpoint().await?;
```

#### Stats

```rust theme={null}
let stats = db.stats().await?;
println!("Network received: {} bytes", stats.network_received_bytes);
println!("Network sent: {} bytes", stats.network_sent_bytes);
println!("WAL size: {} bytes", stats.main_wal_size);
```

## libsql (Remote)

Use the `libsql` crate with the `remote` feature for over-the-wire access to Turso Cloud. This uses pure Rust HTTP — no C compiler needed.

### Installing

```bash theme={null}
cargo add libsql --features remote
```

### Connecting

```rust theme={null}
use libsql::Builder;

let url = std::env::var("TURSO_DATABASE_URL")?;
let token = std::env::var("TURSO_AUTH_TOKEN")?;

let db = Builder::new_remote(url, token).build().await?;
let conn = db.connect()?;
```

### Querying

```rust theme={null}
let mut rows = conn.query("SELECT * FROM users WHERE id = ?1", [1]).await?;
```

## libsql (libSQL)

The `libsql` crate is built on [libSQL](https://github.com/tursodatabase/libsql), the open-source fork of SQLite that powers Turso Cloud today. It is production-ready and battle-tested, and is the right choice when you are working with an existing `libsql`-based codebase.

<Info>
  With `libsql` Embedded Replicas, reads are local and writes are sent to the cloud primary, then reflected back to the replica. Embedded Replicas are fully supported. For new projects that need sync, we recommend the `turso` crate with `turso::sync` — see the [quickstart](/sdk/rust/quickstart).
</Info>

### Embedded Replicas

You can work with [Embedded Replicas](/features/embedded-replicas) that sync from a Turso Cloud database to a local SQLite file. Reads run locally; writes are sent to the cloud primary and then reflected back to the replica:

```rust theme={null}
use libsql::Builder;

let url = std::env::var("TURSO_DATABASE_URL")?;
let token = std::env::var("TURSO_AUTH_TOKEN")?;

let db = Builder::new_remote_replica("local.db", url, token)
    .build()
    .await?;
let conn = db.connect()?;
```

<Snippet file="embedded-replicas-warning.mdx" />

#### Manual Sync

```rust theme={null}
db.sync().await?;
```

#### Sync Interval

```rust theme={null}
use std::time::Duration;

let db = Builder::new_remote_replica("local.db", url, token)
    .sync_interval(Duration::from_secs(300))
    .build()
    .await?;
```

#### Read Your Own Writes

By default, after a `push()`, the next `pull()` waits for the server to fully catch up with your changes before returning — guaranteeing you always read your own writes. This is safer but **much slower**, since the server must process all pending changes. If you can tolerate eventually-consistent reads, disable this for significantly faster pulls:

```rust theme={null}
let db = Builder::new_remote_replica("local.db", url, token)
    .read_your_writes(false)
    .build()
    .await?;
```

### Encryption

<Warning>
  For new projects, we recommend the [`turso`](#turso) crate for local encryption — it is built on the Turso Database engine with better performance and concurrent write support.
</Warning>

To enable encryption on a SQLite file, pass the encryption key value as an argument to the constructor:

<Snippet file="encryption-at-rest-rust.mdx" />

<Info>
  Encrypted databases appear as raw data and cannot be read as standard SQLite databases. You must use the libSQL client for any operations — [learn more](/libsql#encryption-at-rest).
</Info>

### Conditional compilation

The `libsql` crate supports [conditionally compiling](https://doc.rust-lang.org/cargo/reference/features.html#dependency-features) features:

| Feature       | Description                                                           |
| ------------- | --------------------------------------------------------------------- |
| `remote`      | HTTP-only client, pure Rust. No C compiler needed.                    |
| `core`        | Local database only. Requires a C compiler.                           |
| `replication` | Combines `core` with embedded replica support. Requires a C compiler. |
| `encryption`  | Encryption at rest. Requires `cmake`. Not enabled by default.         |

### Simple query

```rust theme={null}
conn.execute("SELECT * FROM users", ()).await?;
conn.execute("SELECT * FROM users WHERE id = ?1", [1]).await?;
```

### Placeholders

<CodeGroup>
  ```rust Positional theme={null}
  conn.execute("SELECT * FROM users WHERE id = ?1", libsql::params![1]).await?;
  ```

  ```rust Named theme={null}
  conn.execute("INSERT INTO users (name) VALUES (:name)", libsql::named_params! { ":name": "Iku" }).await?;
  ```
</CodeGroup>

### Deserialization

```rust theme={null}
use libsql::{de, Builder};

#[derive(Debug, serde::Deserialize)]
struct User {
    name: String,
    age: i64,
}

let mut stmt = conn.prepare("SELECT * FROM users WHERE id = ?1").await?;
let row = stmt.query([1]).await?.next().await?.unwrap();
let user = de::from_row::<User>(&row)?;
```

### Batch Transactions

```rust theme={null}
conn.execute_batch(r#"
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL
  );

  INSERT INTO users (name) VALUES ('Alice');
  INSERT INTO users (name) VALUES ('Bob');
"#).await?;
```

### Interactive Transactions

<CodeGroup>
  ```rust Default theme={null}
  let tx = conn.transaction().await?;

  tx.execute("INSERT INTO users (name) VALUES (?1)", ["Alice"]).await?;
  tx.execute("INSERT INTO users (name) VALUES (?1)", ["Bob"]).await?;

  tx.commit().await?;
  ```

  ```rust Advanced control theme={null}
  use libsql::TransactionBehavior;

  let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).await?;

  tx.execute("UPDATE users SET age = age + 1 WHERE id = ?1", [1]).await?;

  tx.commit().await?;
  ```
</CodeGroup>
