DEV Community

Alex Spinov
Alex Spinov

Posted on

Turso Has a Free API: Distributed SQLite at the Edge With 500 Databases Free

Turso is SQLite at the edge — your database replicates to locations near your users for single-digit millisecond reads. Built on libSQL (open-source SQLite fork). Free tier: 500 databases, 9 GB storage.

Why Turso?

  • Edge-distributed — replicas near your users worldwide
  • SQLite compatible — familiar SQL, lightweight, embedded-friendly
  • 500 DBs free — one DB per user/tenant is viable
  • Embedded replicas — sync SQLite file to your app server
  • HTTP API — works in serverless, edge, Workers

Quick Start

# Install CLI
curl -sSfL https://get.tur.so/install.sh | bash

# Sign up
turso auth signup

# Create database
turso db create my-app

# Get connection info
turso db show my-app --url
turso db tokens create my-app

# Shell
turso db shell my-app
Enter fullscreen mode Exit fullscreen mode

TypeScript SDK

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

const client = createClient({
  url: 'libsql://my-app-username.turso.io',
  authToken: 'your-token',
});

// Query
const result = await client.execute('SELECT * FROM users WHERE active = 1');
console.log(result.rows);

// Parameterized
const user = await client.execute({
  sql: 'SELECT * FROM users WHERE id = ?',
  args: [userId],
});

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

// Transaction
await client.batch([
  { sql: 'INSERT INTO orders (user_id, total) VALUES (?, ?)', args: [1, 99.99] },
  { sql: 'UPDATE users SET order_count = order_count + 1 WHERE id = ?', args: [1] },
], 'write');
Enter fullscreen mode Exit fullscreen mode

HTTP API

URL="https://my-app-username.turso.io"
TOKEN="your-token"

# Execute SQL via HTTP
curl -X POST "$URL/v2/pipeline" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "requests": [
      {"type": "execute", "stmt": {"sql": "SELECT * FROM users LIMIT 10"}},
      {"type": "close"}
    ]
  }'
Enter fullscreen mode Exit fullscreen mode

Embedded Replicas (Ultra-Fast Reads)

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

// Local SQLite file synced with cloud
const client = createClient({
  url: 'file:local-replica.db',
  syncUrl: 'libsql://my-app-username.turso.io',
  authToken: 'your-token',
  syncInterval: 60, // Sync every 60 seconds
});

// Reads from local file (microseconds!)
const users = await client.execute('SELECT * FROM users');

// Writes go to primary, then sync
await client.execute({ sql: 'INSERT INTO users (name) VALUES (?)', args: ['Alice'] });

// Manual sync
await client.sync();
Enter fullscreen mode Exit fullscreen mode

Multi-Tenant (Database Per User)

# Create group
turso group create my-group --location iad

# Add edge locations
turso group locations add my-group lhr  # London
turso group locations add my-group nrt  # Tokyo

# Create per-tenant databases (500 free!)
turso db create tenant-alice --group my-group
turso db create tenant-bob --group my-group
Enter fullscreen mode Exit fullscreen mode

Drizzle ORM + Turso

import { drizzle } from 'drizzle-orm/libsql';
import { createClient } from '@libsql/client';
import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';

const client = createClient({ url: 'libsql://...', authToken: '...' });
const db = drizzle(client);

const users = sqliteTable('users', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  name: text('name').notNull(),
  email: text('email').notNull(),
});

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

Free Tier

Resource Free
Databases 500
Storage 9 GB total
Rows read 1B/month
Rows written 25M/month
Locations 3

Resources


Building edge-first apps? Check my Apify actors or email spinov001@gmail.com.

Top comments (0)