Ваше глобальне веб-застосування гальмує на користувачах з інших регіонів? База даних в одному дата-центрі створює зайву затримку. Ми вирішуємо це за допомогою Turso — розподіленого SQLite на Edge. У цій статті розповімо, як налаштувати Turso з Drizzle ORM та embedded replicas для 0 ms на читання в Cloudflare Workers. Наші інженери мають 10+ років досвіду в distributed systems та реалізували 15+ проєктів з Turso, знизивши середню latency в 3 рази. Порівняно зі звичайним SQLite, Turso знижує глобальну затримку більш ніж у 10 разів. Почніть з безкоштовного аудиту вашого проєкту — зв'яжіться з нами.
Проблеми, які ми вирішуємо
Глобальна затримка. Користувачі з Південної Америки або Азії чекають 200–400 мс, поки запит дійде до сервера в Європі. Turso розміщує репліки в 20+ регіонах, і запит виконується на найближчому вузлі. Write contention. У write-heavy сценаріях SQLite блокує всю базу на час запису. Turso вирішує це реплікацією: запис тільки на primary, читання — з будь-якої репліки. Multi-region без болю. Не потрібно налаштовувати кластер PostgreSQL або думати про синхронізацію. Turso керує реплікацією автоматично, а embedded replica дає нульову затримку на читання в runtime. Turso також підтримує модель database-per-tenant, що спрощує ізоляцію даних для мультитенантних застосунків.
Як працює Turso?
Turso використовує модель primary + replicas:
- Primary — приймає всі записи.
- Replicas — read-only копії на edge (наприклад, Frankfurt, Singapore, São Paulo).
- Embedded Replica — локальна копія SQLite в пам'яті Cloudflare Worker або Node.js процесу.
Для read-heavy застосунків embedded replica знижує latency на читання до нуля — запит не покидає runtime. На одному з проєктів (корпоративний блог з 100k унікальних відвідувачів на місяць) ми досягли часу відповіді SSR менше 50 мс при 99 перцентилі.
Налаштування Turso дозволяє заощадити до 70% витрат на інфраструктуру для read-heavy застосунків порівняно з традиційними рішеннями.
| Характеристика |
Turso |
Традиційний SQLite |
PostgreSQL (один сервер) |
| Read latency (глобально) |
<10 ms |
N/A (локально) |
50–300 ms (залежно від регіону) |
| Write throughput |
~1k ops/s (одна primary) |
~10k ops/s (локально) |
~10k+ ops/s (з шардуванням) |
| Multi-region |
Вбудовано |
Немає |
Потребує налаштування |
| Embedded replica |
Так |
Немає |
Немає |
| Вартість (10 GB) |
Низька |
Безкоштовно |
Середня |
Як налаштувати Turso під ключ
Ми виконуємо налаштування за 2 дні. Ось основні кроки:
- Аудит схеми та навантаження — визначаємо, чи підходить read-heavy сценарій.
- Створення primary та реплік — через CLI обираємо регіони.
- Інтеграція з Drizzle ORM — типізовані запити, міграції.
- Налаштування embedded replica — для Cloudflare Workers або Node.js.
- CI/CD міграцій — автоматичне застосування схем при деплої.
Приклад CLI та коду
# CLI для створення бази та реплік
turso auth login
turso db create myapp --location ams
turso db replicate myapp --location sin
turso db replicate myapp --location gru
turso db show myapp --url
turso db tokens create myapp
// libSQL клієнт з embedded replica
import { createClient } from '@libsql/client';
const db = createClient({
url: process.env.TURSO_DATABASE_URL!,
authToken: process.env.TURSO_AUTH_TOKEN!,
syncUrl: process.env.TURSO_DATABASE_URL!,
syncInterval: 60,
});
await db.sync();
const posts = await db.execute('SELECT id, title FROM articles');
Як Drizzle ORM інтегрується з Turso?
Підключаємо Drizzle для типізованих запитів:
// db/schema.ts
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
export const articles = sqliteTable('articles', {
id: integer('id').primaryKey({ autoIncrement: true }),
title: text('title').notNull(),
slug: text('slug').notNull().unique(),
body: text('body'),
publishedAt: integer('published_at', { mode: 'timestamp' }),
});
// db/client.ts
import { drizzle } from 'drizzle-orm/libsql';
import { createClient } from '@libsql/client';
const client = createClient({
url: process.env.TURSO_DATABASE_URL!,
authToken: process.env.TURSO_AUTH_TOKEN!,
});
export const db = drizzle(client);
const posts = await db.select().from(articles)
.where(isNotNull(articles.publishedAt))
.orderBy(desc(articles.publishedAt))
.limit(10);
Чому варто обрати embedded replica?
Embedded replica дає нульову затримку на читання — запит виконується прямо в runtime, без мережевих викликів. Це критично для SSR на Cloudflare Workers: сторінка рендериться за 10–20 мс замість 100+. Ми гарантуємо, що embedded replica синхронізується з primary не рідше ніж раз на хвилину. Для більшості read-heavy застосунків це прийнятно.
Таблиця етапів та термінів
| Етап |
Тривалість |
Результат |
| Аудит та проєктування |
4 години |
План архітектури, вибір регіонів |
| Налаштування Turso та реплік |
2 години |
Працююча база з репліками |
| Інтеграція з Drizzle |
4 години |
Типізований доступ, перші запити |
| Embedded replica для Workers |
3 години |
Нульова затримка на читання |
| CI/CD міграцій |
2 години |
Автоматичні міграції при деплої |
Що входить в роботу
- Аудит поточної схеми та навантаження.
- Створення primary та реплік в потрібних регіонах.
- Інтеграція з Drizzle ORM (або іншим ORM на вибір).
- Налаштування embedded replica для Cloudflare Workers або Node.js.
- Скрипти для CI/CD міграцій.
- Документація по архітектурі та доступам.
- Навчання команди (1 година онлайн).
- Гарантія підтримки 2 тижні після здачі.
Обмеження Turso: коли варто обрати інше рішення
- Write-heavy (>20% запитів — запис). Всі записи йдуть в primary, вузьке місце.
- Складні аналітичні запити — SQLite не замінює ClickHouse або Timescale.
- Вимоги до PostgreSQL — RLS, розширені типи, PostGIS.
- Високий паралелізм запису — ACID блокування SQLite.
Замовте налаштування Turso під ключ
Оцінимо ваш проєкт безкоштовно: надішліть опис навантаження та схему — ми підберемо оптимальну конфігурацію Turso. Налаштування під ключ за 2 дні. Зателефонуйте або напишіть — обговоримо деталі. Отримайте консультацію по вашому проєкту вже сьогодні.
Serverless-розробка: AWS Lambda, Vercel Functions, Cloudflare Workers, Edge — досвід 7+ років
Ми займаємося serverless-розробкою — проєктуємо, реалізуємо та оптимізуємо рішення на AWS Lambda, Vercel Functions та Cloudflare Workers. Маємо сертифікати AWS та досвід масштабування до 1 млн запитів на день. Оцінимо ваш проєкт безкоштовно — зв’яжіться з нами.
Serverless не означає «без сервера». Сервери є — ви просто не керуєте ними. Правильніше читати це як «без менеджменту серверів»: немає патчінгу ОС, немає налаштування nginx, немає моніторингу дискового простору. Функція отримує подію, обробляє, повертає відповідь. Провайдер вирішує, на чому це запустити.
AWS Lambda: потужність та операційна складність
Lambda — найзріліша платформа з найбільшим набором тригерів: API Gateway, SQS, SNS, S3, DynamoDB Streams, EventBridge. Це важливо для складних event-driven архітектур.
Cold start — головний біль Lambda на Node.js: від 200ms до 1.5s залежно від розміру бандлу та VPC. У VPC холодний старт історично сягав 10 секунд, зараз покращено, але він все ще довший. Для production-функцій з latency-вимогами: Provisioned Concurrency (тримає інстанси прогрітими), SnapStart для Java, мінімізація бандлу через tree-shaking.
Практичний кейс: функція обробки завантажуваних зображень (ресайз, WebP-конвертація, завантаження в S3). Бандл з sharp важив 40MB через нативні бінарники. Рішення — Lambda Layer з sharp, основна функція 800KB. Cold start впав з 3.2s до 400ms — економія становить 87%.
Lambda Layers — спільні залежності між функціями. До 5 шарів на функцію, кожен до 250MB. Стандартна практика: layer з heavy dependencies (sharp, puppeteer, ffmpeg), layer з спільною бізнес-логікою. Інфраструктура Lambda через AWS CDK або Terraform.
| Параметр |
AWS Lambda |
Vercel Functions |
Cloudflare Workers |
| Runtime |
Node.js, Python, Go, Java, .NET (up to 15 min) |
Node.js (up to 300s) |
V8 Isolates (no Node.js API) |
| Cold start |
200ms–1.5s (Node.js) |
~200ms (Node.js) |
<1ms |
| Безкоштовний ліміт |
1M запитів/міс |
100k запитів/міс |
100k запитів/день |
| Реґіони |
AWS Regions (30+) |
Vercel Edge (120+) |
Cloudflare (300+) |
Vercel Functions та Edge Runtime
Vercel Functions — це Lambda під капотом (us-east-1 за замовчуванням), але з мінімальним порогом входу для Next.js-проєктів. API Routes і Route Handlers деплояться автоматично. Serverless функції на Node.js runtime з лімітом в 300 секунд на Vercel Pro.
Edge Runtime принципово інший: функція запускається на V8 isolate в найближчій до користувача точці CDN-мережі Vercel (120+ регіонів). Немає cold start як такого — isolate стартує за ~0ms. Але жорсткі обмеження: немає Node.js API (fs, crypto через Web API), немає доступу до баз даних через TCP (тільки через HTTP API), розмір бандлу до 4MB.
Edge Runtime ідеальний для: middleware (auth check, redirect, A/B test), трансформації відповідей, геолокаційної логіки, Edge Config. Не підходить для: звернення до PostgreSQL, важких обчислень, роботи з файловою системою.
Cloudflare Workers: справжній Edge
Workers запускаються на V8 isolates в 300+ точках присутності Cloudflare. Latency для користувача — буквально найближчий дата-центр. Cold start < 1ms. Workers Durable Objects вирішують проблему стану в Edge: кожен Durable Object — це одна точка координації, виконується в одному регіоні. Ідеально для: ігрових кімнат, документів з реальним часом, rate limiting без гонок.
Workers KV — eventually consistent сховище. Запис поширюється по всіх регіонах за ~60 секунд. Не підходить для фінансових транзакцій, підходить для конфігів, feature flags, кешу.
D1 — SQLite на Edge. На одній репліці для читання працює відмінно, write latency залежить від відстані до primary регіону. Для глобальних write-heavy додатків — не найкращий вибір.
Ecosystem: Hono.js — мінімалістичний роутер, що працює на Workers, Deno, Bun, Node.js. Якщо потрібен єдиний код для Edge і сервера — хороший вибір.
Коли serverless не підходить
Тривалі обчислення (>15 хвилин на Lambda, >30 секунд на Vercel) — потрібен Fargate або звичайний сервер. WebSocket-сервер зі станом — немає постійного процесу. Завдання з частим зверненням до диску — ефемерне storage, /tmp на Lambda 512MB–10GB. Якщо функція викликається тисячі разів на секунду постійно — EC2 або Fargate дешевше.
Vendor lock-in — реальна проблема. Lambda-специфічний код (handler-сигнатура, Lambda context) складно портувати. Hono.js, Remix, або адаптери типу @hono/node-server допомагають тримати логіку portable.
Observability
Без нормального observability serverless — чорний ящик. Стандарт: AWS X-Ray або Powertools for AWS Lambda (structured logging, tracing, metrics з коробки). Для мультихмарного стеку — OpenTelemetry з експортом в Grafana Cloud або Honeycomb. Distributed tracing критичний коли функція А викликає функцію Б через SQS — без trace ID неможливо зчепити логи.
Що входить у роботу
| Deliverable |
Опис |
| Дизайн архітектури |
Границі функцій, event-маршрути, вибір провайдера, схеми даних |
| Реалізація та деплой |
Код на Python/Node.js/Go, CI/CD (GitHub Actions, Terraform), preview deployments |
| Оптимізація холодного старту |
Provisioned Concurrency, Lambda Layers, tree-shaking, ARM |
| Тестування та моніторинг |
Unit/integration тести, X-Ray, alarms (CloudWatch), SLA |
| Документація та навчання |
README, архітектурні діаграми, інструкції для вашої команди |
Процес роботи
Починаємо з аналізу патерну навантаження: якщо трафік непередбачуваний або рідкий — serverless дасть економію; якщо стабільно високий — може виявитися дорожчим. Проєктуємо межі функцій за принципом single responsibility. Розробляємо локально через SST, Wrangler або LocalStack. CI/CD з preview deployments обов’язково.
Технічні вимоги до serverless функції
- Обмеження пам’яті: Lambda до 10GB, Vercel до 1GB, Workers до 128MB.
- Диск: /tmp до 10GB (Lambda), відсутній на Edge.
- Час виконання: Lambda макс 15 хв, Vercel 300 с, Workers 30 с.
- Бандл: Lambda — до 250MB (зі шарами), Vercel — до 50MB, Workers — до 4MB.
Як оптимізувати cold start в AWS Lambda?
Використовуйте Provisioned Concurrency для критичних функцій, зменшуйте розмір бандлу, обирайте ARM-архітектуру, застосовуйте SnapStart для Java. Для edge-функцій без cold start розгляньте Cloudflare Workers.
Що обрати: Cloudflare Workers чи Vercel Functions?
Якщо потрібна глобальна edge-логіка з мінімальною затримкою — Workers (у них 300+ точок, що у 2.5 рази більше ніж Vercel). Якщо використовуєте Next.js і потребуєте повноцінного Node.js runtime — Vercel Functions. Комбінуйте обидва підходи для складних проєктів.
Терміни
Serverless API для стартапу (10–20 функцій): 2–5 тижнів. Міграція монолітного Laravel/Node API на Lambda: 4–10 тижнів залежно від обсягу. Edge Middleware + Workers для глобального продукту: 2–4 тижні. Ми гарантуємо якість на основі 7+ років досвіду та 20+ реалізованих проєктів. Замовте консультацію — отримайте технічну оцінку вашого сценарію.