Embedded Replicas

You can work with embedded replicas that can sync from the remote database to a local SQLite file, and delegate writes to the remote primary database:

package main

import (
  "database/sql"
  "fmt"
  "os"
  "path/filepath"

  "github.com/tursodatabase/go-libsql"
)

func main() {
    dbName := "local.db"
    primaryUrl := "libsql://[DATABASE].turso.io"
    authToken := "..."

    dir, err := os.MkdirTemp("", "libsql-*")
    if err != nil {
        fmt.Println("Error creating temporary directory:", err)
        os.Exit(1)
    }
    defer os.RemoveAll(dir)

    dbPath := filepath.Join(dir, dbName)

    connector, err := libsql.NewEmbeddedReplicaConnector(dbPath, primaryUrl,
      libsql.WithAuthToken(authToken)
    )
    if err != nil {
        fmt.Println("Error creating connector:", err)
        os.Exit(1)
    }
    defer connector.Close()

    db := sql.OpenDB(connector)
    defer db.Close()
}

Embedded Replicas only works where you have access to the file system.

Manual Sync

The Sync function allows you to sync manually the local database with the remote counterpart:

if err := connector.Sync(); err != nil {
    fmt.Println("Error syncing database:", err)
}

Periodic Sync

You can automatically sync at intervals using WithSyncInterval and passing a time.Duration as an argument. For example, to sync every minute, you can use the following code:

syncInterval := time.Minute

connector, err := libsql.NewEmbeddedReplicaConnector(dbPath, primaryUrl,
    libsql.WithAuthToken(authToken),
    libsql.WithSyncInterval(syncInterval),
)

Read Your Writes

By default, the database connection ensures that writes are immediately visible to subsequent read operations initiated by the same connection.

You can disable this behaviour using WithReadYourWrites(false):

connector, err := libsql.NewEmbeddedReplicaConnector(dbPath, primaryUrl,
    libsql.WithAuthToken(authToken),
    libsql.WithReadYourWrites(false),
)

Encryption

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

encryptionKey := "SuperSecretKey"

connector, err := libsql.NewEmbeddedReplicaConnector(dbPath, primaryUrl,
    libsql.WithAuthToken(authToken),
    libsql.WithEncryption(encryptionKey),
)

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.