Skip to main content
โšก Calmops

Turso and LibSQL Complete Guide: Edge Database for Modern Applications

Introduction

Turso is an edge-hosted SQLite database designed for modern applications. Built on LibSQL (a fork of SQLite), it offers embedded replicas for ultra-low latency and simple operation. This guide covers everything you need to get started.

Understanding Turso & LibSQL

What is LibSQL?

LibSQL is an open-source fork of SQLite that adds:

  • HTTP API support
  • Embedded replicas
  • Better replication
  • Rust bindings

What is Turso?

Turso is a managed service built on LibSQL:

  • Edge locations worldwide
  • Embedded replicas for edge
  • Simple pricing
  • Open source
graph TB
    subgraph "Traditional Database"
        Client1[Client]
        DC1[Single Data Center]
        
        Client1 -->|50ms+| DC1
    end
    
    subgraph "Turso + Embedded Replicas"
        Client2[Client]
        Edge[Edge Location]
        Replica[Local Replica]
        DC2[Primary DB]
        
        Client2 -->|1ms| Edge
        Edge -->|sync| Replica
        Replica -->|async| DC2
    end

Why Turso?

Feature Benefit
Edge Ready Sub-millisecond latency
Embedded Replicas Local DB on client
Simple No database ops
Portable Self-host anywhere
Open Source LibSQL is free
Serverless Pay per request

Getting Started

Installation

# Install Turso CLI
brew install/tursodatabase/tap/turso

# Or from source
cargo install turso

# Login
turso auth login

# Create database
turso db create my-app

Connection

// Using @libsql/client
import { createClient } from '@libsql/client/web';

// Edge location (Turso)
const client = createClient({
  url: 'libsql://my-app.turso.io',
  authToken: process.env.TURSO_TOKEN,
});

// Local embedded replica
const localClient = createClient({
  url: 'file:local.db',
});

Embedded Replicas

What are Embedded Replicas?

Embedded replicas sync Turso database locally, enabling:

  • Zero-latency queries
  • Offline support
  • Reduced costs
// Client-side embedded replica
import { createClient } from '@libsql/client/web';

const client = createClient({
  url: 'embedded:local',
  authToken: process.env.TURSO_TOKEN,
});

// Automatically syncs in background
// All queries are instant!

Sync Configuration

// Fine-tune sync behavior
const client = createClient({
  url: 'embedded:local',
  syncUrl: 'libsql://my-app.turso.io',
  authToken: process.env.TURSO_TOKEN,
  syncInterval: 1000, // Sync every second
  authInterval: 30000, // Re-auth every 30s
});

// Manual sync
await client.sync();

Basic Operations

Queries

// Create table
await client.execute(`
  CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT UNIQUE
  )
`);

// Insert
await client.execute({
  sql: 'INSERT INTO users (name, email) VALUES (?, ?)',
  args: ['John', '[email protected]'],
});

// Select
const result = await client.execute('SELECT * FROM users');

// With parameters
const result = await client.execute({
  sql: 'SELECT * FROM users WHERE id = ?',
  args: [1],
});

Transactions

// Batch operations
const batch = await client.batch([
  { sql: 'INSERT INTO users (name) VALUES (?)', args: ['Alice'] },
  { sql: 'INSERT INTO users (name) VALUES (?)', args: ['Bob'] },
  { sql: 'UPDATE users SET name = ? WHERE name = ?', args: ['Carol', 'Alice'] },
]);

Migrations

// Simple migration script
async function migrate(client, migrations) {
  // Create migrations table
  await client.execute(`
    CREATE TABLE IF NOT EXISTS _migrations (
      id INTEGER PRIMARY KEY,
      name TEXT UNIQUE,
      applied_at DATETIME DEFAULT CURRENT_TIMESTAMP
    )
  `);

  for (const migration of migrations) {
    const existing = await client.execute({
      sql: 'SELECT id FROM _migrations WHERE name = ?',
      args: [migration.name],
    });

    if (!existing.rows.length) {
      await client.execute(migration.sql);
      await client.execute({
        sql: 'INSERT INTO _migrations (name) VALUES (?)',
        args: [migration.name],
      });
    }
  }
}

Turso Platform

Database Management

# List databases
turso db list

# Show info
turso db show my-app

# Delete
turso db destroy my-app

# Create replica in region
turso db create my-app --replica us-east

Team Features

# Invite team member
turso org invite [email protected]

# List members
turso org members

Use Cases

Edge Functions

// Cloudflare Workers + Turso
export default {
  async fetch(request) {
    const client = createClient({
      url: 'libsql://my-app.turso.io',
      authToken: TURSO_TOKEN,
    });

    const result = await client.execute('SELECT * FROM users');
    return new Response(JSON.stringify(result.rows));
  }
};

Mobile Apps

// React Native - embedded replica
import { createClient } from '@libsql/client';

const client = createClient({
  url: 'embedded:app.db',
  syncUrl: 'libsql://my-app.turso.io',
  authToken: AUTH_TOKEN,
});

// Works offline!
// Automatically syncs when online

Serverless

// Vercel Edge Functions
export const config = { runtime: 'edge' };

export default async function handler() {
  const client = createClient({
    url: process.env.TURSO_URL,
    authToken: process.env.TURSO_TOKEN,
  });

  const users = await client.execute('SELECT * FROM users LIMIT 10');
  return Response.json(users.rows);
}

Turso vs Others

Feature Turso PlanetScale SQLite
Type LibSQL fork MySQL Original
Edge โœ… Native โŒ โŒ
Embedded โœ… โŒ โœ…
Serverless โœ… โœ… Limited
Open Source โœ… โŒ โœ…
Free Tier 500MB 5GB Free

Best Practices

1. Use Embedded Replicas

// Always prefer embedded on client
const client = createClient({
  url: 'embedded:local-cache.db',
  syncUrl: TURSO_URL,
  authToken: TURSO_TOKEN,
});

2. Handle Conflicts

// Last-write-wins (default)
// Or implement custom conflict resolution

const client = createClient({
  url: 'embedded:local',
  syncUrl: TURSO_URL,
  // Add conflict handler
  onConflict: (local, remote) => {
    // Return winner
    return remote.updated_at > local.updated_at ? remote : local;
  }
});

3. Index Wisely

-- Always index foreign keys
CREATE INDEX idx_posts_user ON posts(user_id);

-- Index frequently queried columns
CREATE INDEX idx_users_email ON users(email);

-- Composite index
CREATE INDEX idx_orders_status_date 
  ON orders(status, created_at);

Conclusion

Turso and LibSQL are perfect for:

  • Edge applications needing low latency
  • Serverless environments
  • Mobile apps needing offline support
  • Simple projectsไธๆƒณ็ฎก็†ๅคๆ‚ๆ•ฐๆฎๅบ“
  • Portability - self-host anywhere

Start with Turso’s free tier, add embedded replicas for speed.


External Resources

Comments