Celý víkend jsem ladil novou aplikaci Kveez.app, nasadil jsem ji na Cloudflare Workers s využitím jejich D1 databáze a krásně to běželo.
Jenže pak aplikaci pustíte mezi lidi… a realita vás profackuje.
Jen co jsem uvedl svou aplikaci na veřejnost, zjistil jsem, že D1 je sice skvělá technologie, ale pro můj use-case už začíná být těsná. Bylo na čase vytáhnout těžší kalibr: Prisma Postgres v kombinaci s Cloudflare Hyperdrive.
Proč vůbec opouštět Cloudflare D1?
D1 je super. Je to SQLite na steroidech, replikované po celém světě. Ale SQLite má své limity, zvlášť v jedno-vláknovém přístupu a pozoroval jsem výkyvy v přístupu k DB. Hlavní motivace pro přesun byla:
- Škálovatelnost: Postgres zvládá výrazně větší zátěž a souběžné zápisy (concurrency) lépe než SQLite.
- Pokročilé funkce: Potřeboval jsem věci, které SQLite buď neumí, nebo se v něm dělají složitě – Full-text search, nativní JSON operace nebo Window functions.
- Ekosystém: Kolem Postgresu existuje masivní sada nástrojů pro monitoring, správu a optimalizaci.
Co je to ten Hyperdrive?
Cloudflare Workers běží na Edge (na okraji sítě), zatímco databáze je obvykle na jednom místě (v mém případě EU). Otevírání nového TCP spojení pro každý request by bylo pomalé.
Cloudflare Hyperdrive funguje jako chytrá proxy a connection pooler. Udržuje sadu otevřených spojení k databázi a Worker se připojuje k nejbližšímu uzlu Hyperdrive. Výsledek? Dramatické zrychlení dotazů.
Kroky migrace
Instalace Postgres driveru
npm install pg @types/pg
Nastavení Hyperdrive ve wrangler.jsonc
Hyperdrive musíte nejprve vytvořit v Cloudflare dashboardu nebo přes CLI (wrangler hyperdrive create). Získáte ID, které vložíte do konfigurace:
{
"hyperdrive": [{
"binding": "HYPERDRIVE",
"id": "your-hyperdrive-id",
"localConnectionString": "postgres://user:pass@localhost:5432/db"
}]
}
Migrace dat
SQLite a Postgres mluví podobným jazykem (SQL), ale mají jiné dialekty.
Krok A: Export z D1
wrangler d1 export NAZEV_VASI_DB --output=dump.sql
Krok B: Ruční úprava SQL dumpu. Otevřete dump.sql v editoru a připravte se na “najdi a nahraď”. Postgres bude křičet na následující věci:
- Smažte
PRAGMA: Příkazy jakoPRAGMA foreign_keys=OFF;Postgres nezná. - Primární klíče: Změňte
INTEGER PRIMARY KEY AUTOINCREMENTnaSERIAL PRIMARY KEY(neboGENERATED ALWAYS AS IDENTITYpro novější verze PG). - Uvozovky: Pokud máte názvy sloupců v
camelCase(např.userId), musíte je v Postgresu dát do uvozovek"userId", jinak je bude hledat jakouserida spadne to. - Funkce: Funkce se liší. Například
MAX(a,b)musíte přepsat naGREATEST(a,b)v Postgresu.
Krok C: Import do Postgres
psql -h host -U user -d database -f dump.sql
Úprava aplikace (ORM a Auth)
Pokud používáte moderní knihovny, je přechod hračka. Já používám Better Auth, kde stačila změna jednoho řádku:
// Před (D1/SQLite)
database: { db, type: "sqlite" }
// Po (Postgres)
database: { db, type: "postgres" }
Pasti a problémy (Troubleshooting)
Zrádná cache v Hyperdrive
Hyperdrive není jen o connection poolingu, má i svou cache vrstvu. Ta byla (možná defaultně, možná mou chybou) zapnutá hned po nastavení Prisma DB. Problém: Provedl jsem update v databázi, ale aplikace mi stále vracela stará data.
Řešení: Zkontrolujte nastavení cachování v Cloudflare dashboardu u konfigurace Hyperdrive, zvláště pokud při vývoji vidíte nekonzistentní data.
D1 Batch API nefunguje
Při optimalizaci pro D1 jsem využíval env.DB.batch(), což umožňuje poslat více SQL dotazů najednou a ušetřit round-trips. Toto je ale D1 specific funkce.
S Postgresem musíte použít standardní Promise:
// Před (D1 Batch)
// Rychlé, ale specifické pro D1
await env.STATS_DB.batch([query1, query2, query3]);
// Po (standardní Promise.all)
// Funguje všude (D1 i Postgres), ale technicky jde o více requestů
await Promise.all([
q1.execute(),
q2.execute(),
q3.execute()
]);
Závěr
Ihned po migraci na Postgres pozoruji významné zrychlení přístupu do DB. Zmizely občasné výkyvy (spikes), které jsem vídal u D1 při vyšší zátěži.
Největší obavy jsem měl z latence, protože databáze už není distribuovaná po celém světě. V Cloudflare Dashboardu vidím odezvu Prisma DB (přes Hyperdrive) okolo 41 ms.
Worker i Prisma DB mám umístěny v EU, je to skvělý výsledek, který je pro uživatele nerozeznatelný od lokální DB, ale s plnou silou a funkcemi Postgresu v zádech.