DEV Community

Alex Spinov
Alex Spinov

Posted on

Turso Has a Free API — SQLite at the Edge with Embedded Replicas

Turso is SQLite for production — a distributed database that runs at the edge with embedded replicas. Your data lives close to your users, reads are instant, and you get a generous free tier.

Why Turso?

  • SQLite at the edge — replicas in 30+ locations worldwide
  • Embedded replicas — sync a local SQLite copy into your app for zero-latency reads
  • Free tier — 9GB storage, 500 databases, 25M row reads/month
  • libSQL — open-source fork of SQLite with extensions

Quick Start

# Install CLI
brew install tursodatabase/tap/turso

# Login
turso auth login

# Create database
turso db create myapp

# Get connection URL
turso db show myapp --url

# Create auth token
turso db tokens create myapp
Enter fullscreen mode Exit fullscreen mode

Using with TypeScript

npm install @libsql/client
Enter fullscreen mode Exit fullscreen mode
import { createClient } from '@libsql/client';

const db = createClient({
  url: 'libsql://myapp-username.turso.io',
  authToken: process.env.TURSO_AUTH_TOKEN,
});

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

// Insert
await db.execute({
  sql: 'INSERT INTO users (name, email) VALUES (?, ?)',
  args: ['Alice', 'alice@example.com'],
});

// Query
const result = await db.execute('SELECT * FROM users');
console.log(result.rows);
Enter fullscreen mode Exit fullscreen mode

Embedded Replicas (Zero-Latency Reads)

const db = createClient({
  url: 'file:local-replica.db',
  syncUrl: 'libsql://myapp-username.turso.io',
  authToken: process.env.TURSO_AUTH_TOKEN,
});

// Sync from remote
await db.sync();

// Reads are instant (local file)
const users = await db.execute('SELECT * FROM users');

// Writes go to remote, then sync back
await db.execute({
  sql: 'INSERT INTO users (name, email) VALUES (?, ?)',
  args: ['Bob', 'bob@example.com'],
});
Enter fullscreen mode Exit fullscreen mode

With Drizzle ORM

import { drizzle } from 'drizzle-orm/libsql';
import { createClient } from '@libsql/client';

const client = createClient({
  url: process.env.TURSO_URL!,
  authToken: process.env.TURSO_AUTH_TOKEN,
});

const db = drizzle(client);

const users = await db.select().from(usersTable);
Enter fullscreen mode Exit fullscreen mode

Branching (like Git for databases)

# Create a branch
turso db create myapp-staging --from-db myapp

# Use for testing, then destroy
turso db destroy myapp-staging
Enter fullscreen mode Exit fullscreen mode

Multi-Tenant with Database-per-Tenant

// Create database per tenant
const createTenantDb = async (tenantId: string) => {
  const db = createClient({
    url: `libsql://myapp-${tenantId}-username.turso.io`,
    authToken: process.env.TURSO_AUTH_TOKEN,
  });
  await db.execute(`CREATE TABLE IF NOT EXISTS data (...)`);
  return db;
};
Enter fullscreen mode Exit fullscreen mode

Need to store scraped data at the edge? Check out my Apify actors for web scraping + Turso storage pipeline. Email spinov001@gmail.com for custom solutions.

Turso, D1, or Neon — which serverless database do you use? Share below!

Top comments (0)