Secure, test, and operate

Measure pools, queries, and failures

Observe connection reuse, database pressure, cache behavior, query latency, and errors before tuning pool size or cache time.

Hyperdrive removes the connection setup cost. It does not remove slow queries, and it can’t give your database more capacity than it has. So you watch both sides: what Cloudflare sees and what the database sees.

Two dashboards, one request

On the Cloudflare side, each Hyperdrive configuration has a Metrics tab. It shows query count, latency, cache hits, and the connection pool: how many origin connections are open, how many clients are waiting for one, and the configured maximum.

Waiting clients is the number I check first. If it spikes, requests are queuing for a connection. Either the pool is too small or queries hold connections too long.

On the database side, count what Hyperdrive is holding open:

select count(*) from pg_stat_activity where usename = 'app_worker';

That number should sit below the pool limit you configured, and well below the database’s max_connections.

Start small

Every configuration gets at least 5 origin connections. Raise the limit only when the metrics say you need it:

npx wrangler hyperdrive update 57b7076f58be42419276f058a8968187 --origin-connection-limit=20

Keep it below what the origin allows. The limit is soft. During a network failure Hyperdrive may open a few extra connections to stay available, and you don’t want those to be the ones that hit the database ceiling.

Measure one request end to end

Measure one request with a narrow query and a request ID:

select id, title
from notes
where user_id = $1
order by created_at desc
limit 20;

Record application duration, database duration, rows returned, pool errors, and the query plan. Repeat after a warm request. If the result is slow, do not assume geographic distance is the cause: a scan, lock, or exhausted origin pool can dominate the same request.

Keep an escape hatch

Know how to disable query caching quickly, and keep a direct connection path you can switch to. If a stale cached result causes harm, you want to flip a switch, not debug under pressure. A --caching-disabled configuration, created in advance and already bound, is that switch.

Try this in a practice environment: run a bounded load test, say 50 concurrent requests for a minute, and line up the Worker timings with the database connection count and query latency. If waiting clients climb while the database sits idle, the pool is the bottleneck. If the database CPU climbs, the queries are.

Lesson completed