Why we didn't use Hyperdrive
· AKHBaig
The premise we had to check
When we looked at deploying the AutoSugges control plane to Cloudflare Workers, the working assumption was that Cloudflare Hyperdrive was required to reach PostgreSQL at all — every server-side data-access module in apps/web builds its SQL executor over postgres, a raw TCP driver, and raw TCP was believed unavailable on Workers.
That premise turned out to be false, and we checked it rather than argued it. The postgres driver we already depend on ships a workerd-compatible build whose polyfill opens connections through Cloudflare's raw-socket API rather than Node's net module. A direct connectivity probe confirmed it: a Worker can open a TLS connection straight to PostgreSQL. Outbound TCP from a Worker to Postgres just works.
Why we still didn’t adopt Hyperdrive
Hyperdrive is a pooling and caching optimization, not a prerequisite — and adopting it anyway would have cost more than it bought.
- It changes a boundary for no proven gain. Hyperdrive supplies its connection string through a Worker binding, not an environment variable, which would ripple a contract change into every data-access module in the app.
- next dev has no bindings, so a binding-shaped contract needs a second, conditional connection path for local development — meaning the path that runs in production is not the one anyone develops against.
- Supabase's own pooler already pools; Hyperdrive would place a second pool in front of a pool, with neither measured.
- And plainly: YAGNI. A product, a binding, a config resource and a per-environment id, added against a problem nobody had actually observed.
A correctness constraint, not a performance one
The investigation started from a performance question — connection pressure from many short-lived Workers isolates — and found a correctness one instead. Workers' isolate model doesn't tolerate the ordinary Node.js pattern of caching a database connection at module scope: a socket opened for one request does not belong to the next one, so a connection has to be scoped to the request that opens it, opened and closed within it.
Hyperdrive would not have changed this either way — the constraint is about connection lifetime against the isolate model, not about pooling. On Workers, a connection's lifetime is a correctness property before it is a performance one, and it holds whether or not a pooling layer sits in front of PostgreSQL.