2026-06-01infra
Request-scoped DB connections via Cloudflare Hyperdrive
- Change: Reworked the database connection layer to stop sharing a
pg.Poolacross requests on Cloudflare Workers.lib/db.tsnow resolves a Drizzle instance per request — keyed by the request'sExecutionContextviagetCloudflareContext()— backed by a Cloudflare Hyperdrive binding (env.HYPERDRIVE.connectionString). AglobalThis-cached fallback pool (readingDATABASE_URL/POSTGRES_URL) is retained fornext dev,next build, and scripts. The exporteddbis now a transparentProxyso existingimport { db }call sites are unchanged. Added ahyperdrivebinding towrangler.jsoncandinitOpenNextCloudflareForDev()innext.config.tsso the binding is present in local dev. - Why: On Workers, a TCP socket opened in one request cannot be reused by a later request — the globally cached pool handed stale, cross-request connections to new requests, which hung the Worker until the runtime canceled it ("detected that your Worker's code had hung"). Per-request connections eliminate the reuse, and Hyperdrive provides edge-side connection pooling so the per-request connect stays cheap.
- Affected Modules:
lib/db.ts,next.config.ts,wrangler.jsonc,cloudflare-env.d.ts - Trade-offs:
- Pro: Removes the request-hang failure mode; Hyperdrive pools connections at the edge and lowers DB round-trip latency; call sites are untouched thanks to the proxy.
- Con: Requires a one-time Hyperdrive provisioning step (
wrangler hyperdrive create) and a realidinwrangler.jsonc; theProxyindirection and per-request pool lookup add a small amount of overhead and conceptual complexity over a plain singleton.