Что такое Turso: распределённая SQLite для edge и мультитенантных приложений
Turso — это edge-hosted distributed database, построенная на libSQL — открытом форке SQLite. Если коротко: Turso берёт SQLite (самую простую и быструю встраиваемую БД) и добавляет то, чего ей не хватало для modern web — глобальную репликацию, конкурентную запись, HTTP API и поддержку тысяч баз данных в одном аккаунте.
В 2025-2026 годах компания Turso прошла две стадии: начала с libSQL-based Turso Cloud, а в 2025 году анонсировала полный переход на новый Turso — полностью переписанную SQLite-совместимую СУБД на Rust с native async, vector search и multi-writer поддержкой.
libSQL, Turso Cloud и новый Turso: разберём путаницу
В экосистеме Turso три разных проекта:
libSQL — open-source форк SQLite на C. Поддерживает HTTP API, встроенные реплики (embedded replicas), шифрование, vector search. Это то, что работает в Turso Cloud сегодня. Полностью совместим с SQLite — тот же формат файла, тот же SQL-диалект.
Turso Cloud — managed DBaaS поверх libSQL. Вы получаете базы данных через дашборд или CLI, они реплицируются в глобальную сеть из 35+ регионов. Каждая база — отдельная libSQL-инстанция. Бесплатный тариф: 500 баз, 9 GB хранилища.
Turso (Rust) — новое поколение (2025+). Полный переврайт SQLite на Rust с native async, concurrent writes (решена single-writer проблема), WASM поддержкой и улучшенным vector search. Пока в Alpha (май 2026), но это будущее платформы.
Для production в 2026 году: используйте Turso Cloud + libSQL — стабильный, production-ready продукт с хорошей экосистемой.
Почему SQLite на edge — революционная идея
Традиционный web-запрос к базе данных:
Пользователь (Москва) → Vercel Edge (Франкфурт) → PostgreSQL (us-east-1)
Latency: 20ms (edge) + 120ms (база) = 140ms на каждый DB-запрос
С Turso Embedded Replicas:
Пользователь (Москва) → Cloudflare Worker (Москва) → Turso Embedded Replica (локально)
Latency: 5ms (edge) + 0.1ms (локальная реплика) = 5.1ms на каждый DB-запрос
Embedded replica — это локальная копия базы данных, которая работает прямо внутри вашего edge-функции. Записи идут в primary (центральная БД), читают — из локальной реплики без сетевого запроса.
// Embedded replica в Cloudflare Worker
import { createClient } from '@libsql/client'
const client = createClient({
url: 'file:local.db', // локальный файл
syncUrl: process.env.TURSO_URL, // primary Turso Cloud
authToken: process.env.TURSO_TOKEN,
syncInterval: 60, // синхронизация каждые 60 секунд
})
// Чтение — из локальной реплики (0.1ms)
const users = await client.execute('SELECT * FROM users WHERE id = ?', [userId])
// Запись — в primary через HTTP (10-30ms, зависит от региона)
await client.execute(
'INSERT INTO users (name, email) VALUES (?, ?)',
[name, email]
)
Настройка Turso: от нуля до production
Создание базы и подключение
# Установка CLI
curl -sSfL https://get.tur.so/install.sh | bash
# Логин
turso auth login
# Создание базы
turso db create myapp --location fra # Frankfurt
# Получить credentials
turso db show myapp
turso db tokens create myapp
# .env
TURSO_URL=libsql://myapp-username.turso.io
TURSO_AUTH_TOKEN=eyJhbGci...
Подключение из Node.js / Bun.js + Drizzle
npm install @libsql/client drizzle-orm drizzle-kit
// lib/db.ts
import { createClient } from '@libsql/client'
import { drizzle } from 'drizzle-orm/libsql'
import * as schema from './schema'
const client = createClient({
url: process.env.TURSO_URL!,
authToken: process.env.TURSO_AUTH_TOKEN!,
})
export const db = drizzle(client, { schema })
// lib/schema.ts
import { sqliteTable, text, integer, real } from 'drizzle-orm/sqlite-core'
import { sql } from 'drizzle-orm'
export const users = sqliteTable('users', {
id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),
name: text('name').notNull(),
email: text('email').notNull().unique(),
plan: text('plan', { enum: ['free', 'pro', 'enterprise'] }).default('free'),
createdAt: integer('created_at', { mode: 'timestamp' })
.default(sql`(unixepoch())`),
})
export const posts = sqliteTable('posts', {
id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),
title: text('title').notNull(),
content: text('content'),
authorId: text('author_id').references(() => users.id),
published: integer('published', { mode: 'boolean' }).default(false),
})
// Типобезопасные запросы
import { db } from '@/lib/db'
import { users, posts } from '@/lib/schema'
import { eq, and, isNotNull } from 'drizzle-orm'
// Список публикаций с автором
const publishedPosts = await db
.select({
id: posts.id,
title: posts.title,
authorName: users.name,
})
.from(posts)
.leftJoin(users, eq(posts.authorId, users.id))
.where(eq(posts.published, true))
.all()
Мультитенантность с Turso: одна БД на клиента
Самая мощная особенность Turso — бесплатный тариф даёт 500 баз данных. Это позволяет строить SaaS с полной изоляцией данных: у каждого клиента своя база данных, а не своя схема/row-level security в общей базе.
// SaaS: создание базы для нового тенанта
import { createClient as createTursoApiClient } from '@tursodatabase/api'
const tursoApi = createTursoApiClient({
token: process.env.TURSO_API_TOKEN!,
org: process.env.TURSO_ORG!,
})
export async function createTenantDatabase(tenantId: string) {
// Создаём базу данных для тенанта
const db = await tursoApi.databases.create({
name: `tenant-${tenantId}`,
group: 'default',
})
// Создаём auth token для этой базы
const token = await tursoApi.databases.createToken(`tenant-${tenantId}`)
// Инициализируем схему
const client = createClient({
url: `libsql://${db.hostname}`,
authToken: token.jwt,
})
await client.execute(`
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
created_at INTEGER DEFAULT (unixepoch())
)
`)
// Сохраняем connection info в master-базе
await masterDb.execute(
'INSERT INTO tenants (id, db_url, db_token) VALUES (?, ?, ?)',
[tenantId, `libsql://${db.hostname}`, token.jwt]
)
return { url: `libsql://${db.hostname}`, token: token.jwt }
}
Преимущества этого подхода:
- Полная изоляция данных (невозможна утечка между тенантами)
- Простота compliance (GDPR: удалить данные = удалить базу)
- Независимые бэкапы и восстановление на уровне тенанта
- Возможность давать тенанту прямой доступ к его базе
Сравнение Turso с аналогами
| Параметр | Turso | Neon | Cloudflare D1 | PlanetScale | Supabase | |---|---|---|---|---|---| | Движок | libSQL (SQLite) | PostgreSQL | SQLite | MySQL | PostgreSQL | | Edge-поддержка | ★★★★★ | ★★★★☆ | ★★★★★ | ★★★☆☆ | ★★★☆☆ | | Мультитенант (N баз) | ★★★★★ (500 free) | ★★★☆☆ | ★★★★☆ | ★★☆☆☆ | ★★★☆☆ | | Бесплатный тариф | 500 баз, 9GB | 512MB | 5GB, 25M чтений | Закрыт | 500MB | | Embedded replicas | ★★★★★ | ✗ | ✗ | ✗ | ✗ | | Совместимость | SQLite | PostgreSQL | SQLite | MySQL | PostgreSQL | | Горизонт. масштаб. | ★★★★☆ | ★★★★☆ | ★★★★★ | ★★★★☆ | ★★★☆☆ | | Российский доступ | Да (API) | Да | Проблемы | Закрыт | Проблемы | | Цена Pro | $29/мес | $19/мес | $5/мес | — | $25/мес |
Когда выбирать Turso
Turso — оптимальный выбор если:
- Нужен edge-first подход с минимальной latency
- Строите SaaS с мультитенантностью (одна БД на тенанта)
- Ваш стек: Cloudflare Workers / Vercel Edge + JS/TS
- Хотите SQLite-совместимость (Drizzle, Better SQLite3 API)
- Нужна глобальная репликация без сложной настройки
Выбирайте Neon (PostgreSQL) если:
- Нужен полноценный PostgreSQL (pgvector, PostGIS, RLS)
- Сложные SQL-запросы с JOIN, оконными функциями
- Команда хорошо знает PostgreSQL
- Интеграция с Supabase-экосистемой
Выбирайте Cloudflare D1 если:
- Уже используете Cloudflare Workers
- Нужна максимально дешёвая edge-база
- Проект полностью в экосистеме Cloudflare
Turso в России: вопросы доступности
Turso — американская компания, но в отличие от PlanetScale (полностью закрыл доступ из РФ) или части Supabase cloud — API Turso доступно из России в 2026 году (проверено). Оплата: иностранной картой (Visa/Mastercard с зарубежных аккаунтов) или криптовалютой через посредников.
Для российских проектов, которым важна доступность: self-hosted libSQL — всегда работает:
# Self-hosted sqld (libSQL server)
docker run -p 8080:8080 \
-e SQLD_NODE=primary \
ghcr.io/tursodatabase/libsql-server:latest
# Подключение через @libsql/client
const client = createClient({
url: 'http://localhost:8080',
// authToken не нужен для localhost
})
Бэкап Turso баз данных
Turso Cloud хранит данные в глобальной инфраструктуре с репликацией. Но для критических данных и compliance нужны собственные бэкапы:
# Экспорт базы через Turso CLI
turso db shell myapp .dump > backup.sql
# Автоматический экспорт через скрипт
#!/bin/bash
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
turso db shell myapp .dump | gzip > backups/turso_${TIMESTAMP}.sql.gz
Через dbsend.ru (для libSQL self-hosted или как SQL-dump):
# Для self-hosted sqld через HTTP
dbsend backup \
--db=libsql://localhost:8080 \
--destination=s3://bucket/turso \
--schedule=daily
# Для Turso Cloud через dump
dbsend backup \
--pre-command="turso db shell myapp .dump > /tmp/turso.sql" \
--path=/tmp/turso.sql \
--destination=s3://bucket/turso-cloud \
--schedule="0 */6 * * *"
FAQ
Turso бесплатный?
Бесплатный тариф Turso Cloud: 500 баз данных, 9 GB общего хранилища, 1 миллиард чтений/месяц, 25 миллионов записей/месяц. Для большинства стартапов и MVP этого хватает надолго. Платный тариф — от $29/мес (Scaler) с увеличенными лимитами.
В чём разница libSQL и SQLite?
libSQL — форк SQLite с расширениями: HTTP API (работает в edge без TCP), embedded replicas (локальная реплика с синхронизацией), шифрование на уровне клиента, vector search, async I/O. Полностью обратно совместим с SQLite — те же файлы, тот же SQL. Turso Cloud построен на libSQL.
Работает ли Drizzle с Turso?
Да, Drizzle имеет нативный адаптер для libSQL/Turso: drizzle-orm/libsql. Поддерживает все операции включая migrations. Это один из рекомендуемых стеков для Turso в 2026 году. Prisma также поддерживает libSQL начиная с версии 5.4.
Как Turso решает проблему single-writer SQLite?
В Turso Cloud через координацию записей на уровне инфраструктуры — все записи роутируются в primary, реплики синхронизируются асинхронно (eventual consistency для чтения). В новом Turso на Rust реализованы concurrent writes через MVCC-подобный механизм — несколько писателей работают параллельно. Это кардинальное отличие от обычного SQLite.
Можно ли перенести данные из PostgreSQL в Turso?
Да, но с ограничениями: Turso/SQLite не поддерживает все типы данных PostgreSQL (arrays, JSONB индексы, специфические функции). Процесс: экспорт из PostgreSQL в SQL, трансформация типов данных (SERIAL → INTEGER, JSONB → TEXT), импорт в libSQL. Для сложных схем лучше переписать миграции. Инструмент: pgloader с конфигурацией под SQLite.
Что такое группы баз данных в Turso?
Groups — механизм для управления регионами репликации. Все базы в одной группе реплицируются в одинаковый набор регионов. Например, группа europe с регионами fra (Франкфурт) и ams (Амстердам) гарантирует, что данные доступны в обоих ДЦ. Для мультитенантного SaaS все тенант-базы помещают в одну группу — они автоматически получают одинаковое географическое распределение.