Files
2nd/10_Wiki/Topics/Coding/DB_Serverless_Edge.md
T
2026-05-09 21:08:02 +09:00

7.3 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
db-serverless-edge Serverless / Edge DB — Neon / Turso / D1 / Hyperdrive Coding draft B conceptual 2026-05-09 2026-05-09
database
serverless
edge
vibe-coding
language applicable_to
TS
Backend
Neon
Turso
Cloudflare D1
Hyperdrive
libSQL
edge SQLite
branching DB

Serverless / Edge DB

Lambda / Edge function = connection pool 어려움. Neon (Postgres HTTP), Turso (libSQL), Cloudflare D1, Hyperdrive (PG proxy). Branching, scale-to-zero, low latency.

📖 핵심 개념

  • HTTP-based: connection 없음 — REST 같이.
  • Branching: production data → dev branch.
  • Scale-to-zero: 안 쓰면 stop.
  • Edge: 사용자 가까이.

💻 코드 패턴

Neon (Postgres serverless)

import { neon } from '@neondatabase/serverless';

const sql = neon(process.env.DATABASE_URL!);

// HTTP API — connection 없음
const users = await sql`SELECT * FROM users WHERE id = ${userId}`;
const user = users[0];
// 또는 Pool (Edge runtime)
import { Pool } from '@neondatabase/serverless';

const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const r = await pool.query('SELECT * FROM users WHERE id = $1', [id]);

→ Standard Postgres + HTTP transport.

Neon branching (development)

# Branch 생성
neon branches create --name dev-feature-x --parent main

# Schema migration test
DATABASE_URL=$(neon connection-string dev-feature-x) yarn migrate:up

# Production 영향 없음
# Done → branch delete

→ Git-like database.

Turso (libSQL = SQLite fork)

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

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

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

console.log(r.rows);

→ SQLite + replication + edge.

Turso embedded replica (zero-latency read)

const turso = createClient({
  url: 'file:local.db',
  syncUrl: 'libsql://my-db.turso.io',
  authToken,
  syncInterval: 60,  // 60s sync
});

await turso.sync();

// Read = local file (0 ms)
const r = await turso.execute('SELECT * FROM users');

→ Read = local, write = remote, 자동 sync.

Cloudflare D1

// wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "my-app"
database_id = "..."
// Worker
export default {
  async fetch(req: Request, env: Env) {
    const r = await env.DB.prepare('SELECT * FROM users WHERE id = ?').bind(userId).first();
    return Response.json(r);
  },
};

→ SQLite + 글로벌 read replica.

Hyperdrive (CF, Postgres / MySQL accelerator)

// wrangler.toml
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "..."  # PG / MySQL connection
import postgres from 'postgres';

export default {
  async fetch(req: Request, env: Env) {
    const sql = postgres(env.HYPERDRIVE.connectionString);
    const r = await sql`SELECT * FROM users WHERE id = ${id}`;
    return Response.json(r);
  },
};

→ Hyperdrive 가 connection pool + cache. CF Worker 안 일반 PG client.

PlanetScale (MySQL serverless)

import { Client } from '@planetscale/database';

const client = new Client({
  url: process.env.DATABASE_URL,
});
const conn = client.connection();

const r = await conn.execute('SELECT * FROM users WHERE id = ?', [id]);

→ MySQL HTTP. Branching 같이.

Branching workflow (Neon / PlanetScale)

# .github/workflows/preview.yml
- name: Create branch for PR
  run: neon branches create --name pr-${{ github.event.number }} --parent main

- name: Run migrations
  run: DATABASE_URL=$BRANCH_URL yarn migrate:up

- name: Deploy preview
  run: vercel deploy --env DATABASE_URL=$BRANCH_URL

- name: On PR close — delete
  run: neon branches delete pr-${{ github.event.number }}

→ 매 PR = 자체 DB.

Scale-to-zero

Neon:    안 쓰면 compute stop. 다음 query 가 cold start (~500ms).
Turso:   항상 활성 (작은 비용).
D1:      활성.
Hyperdrive: pool + cache.

→ Low-traffic 앱 = Neon 가 cheap.

Cost (대략)

Neon:     Free tier — 0.5GB / 1 project. Paid $19/month.
Turso:    Free 9GB / 500 DBs. Paid scaled.
D1:       Free 5GB / 25M reads/day. Paid pennies/M.
Hyperdrive: CF Workers paid.
PlanetScale: Free tier — but 2024 가격 변경.

사용자 관점 latency

일반 RDS (us-east-1) + Lambda (us-east-1):  ~5-20ms query
Neon HTTP + Lambda:                          ~10-30ms
Turso embedded replica:                      ~0ms read
D1 (CF worker, edge):                        ~1-5ms (local region)
Hyperdrive (CF worker → cached):             ~1-5ms cached

Drizzle 통합

import { drizzle } from 'drizzle-orm/neon-http';
import { neon } from '@neondatabase/serverless';

const sql = neon(process.env.DATABASE_URL!);
const db = drizzle(sql);

const users = await db.select().from(usersTable).where(eq(usersTable.id, id));
// Turso
import { drizzle } from 'drizzle-orm/libsql';
import { createClient } from '@libsql/client';

const client = createClient({ url, authToken });
const db = drizzle(client);

Prisma (구식 — Edge 어려움)

// Prisma 의 Data Proxy / Accelerate 필요
// 또는 driver adapter (Neon)
import { PrismaClient } from '@prisma/client';
import { PrismaNeon } from '@prisma/adapter-neon';
import { neon } from '@neondatabase/serverless';

const sql = neon(process.env.DATABASE_URL!);
const adapter = new PrismaNeon(sql);
const prisma = new PrismaClient({ adapter });

Vector search (Neon pgvector / Turso SQLite vss)

-- Neon = pgvector 그대로
CREATE EXTENSION vector;
CREATE TABLE docs (... embedding VECTOR(1536));

-- Turso = sqlite-vss extension

Migration tools

# Neon — branch 로
neon branches create --name migration-test
DATABASE_URL=$BRANCH yarn migrate:up
# Verify
neon branches delete migration-test

# 또는 atlas / drizzle-kit / prisma migrate

동시성 / write

Neon:  읽기 다중 (read replica) / write 단일.
Turso: read 다중 / write 한 곳 (primary).
D1:    write 한 region / read 글로벌.

→ 분산 write = 다른 system 필요.

단점

Neon:    PG 호환 — but 일부 extension 제약.
Turso:   SQLite 가 OLTP 만. analytic X.
D1:      SQLite 같음 + 일부 extension X.
Hyperdrive: 자체 DB X — 기존 PG 가까이.
PlanetScale: FK 제약 (online schema change 위해).

🤔 의사결정 기준

상황 추천
Vercel + 새 프로젝트 Neon
Cloudflare Workers D1 / Hyperdrive
글로벌 low-latency read Turso embedded
Postgres 기존 Hyperdrive
MySQL PlanetScale
큰 OLTP RDS / Aurora (전통)
Analytic DuckDB / ClickHouse

안티패턴

  • Lambda + 일반 PG 직접: connection 폭발. HTTP / Hyperdrive.
  • Turso 가 analytic 가정: SQLite. DuckDB.
  • Branch 생성 + 자동 delete X: 비용.
  • Cold start 무관 prod: latency. Pool / always-on.
  • Edge + complex JOIN: cross-region 비싸.
  • Prepared statement cache 무: 매번 parse.

🤖 LLM 활용 힌트

  • Vercel / Next = Neon 디폴트.
  • CF Workers = D1 / Hyperdrive.
  • Local-first = Turso embedded.
  • Branching = git-like dev.

🔗 관련 문서