Cloudflare Hyperdrive: Keep Your Existing Postgres, Move Your Compute

Quick answer: Hyperdrive is a connection pooler and query cache that sits between Cloudflare Workers and the PostgreSQL or MySQL database you already run. It exists because a Worker can open only 6 outgoing connections per invocation, and because traditional databases have a hard connection ceiling that a globally distributed serverless runtime will exhaust in minutes. You do not migrate your database, change your schema, or drop any extensions โ€” you take your existing connection string, create a config, and bind it to your Worker. The one thing you must understand before switching it on is that the cache does not invalidate on write.

The single biggest reason engineering teams reject Cloudflare Workers is the database. They already run PostgreSQL. The schema is stable, the reports depend on it, the backups have been tested, and someone knows how to restore it. What they want is to move compute to the edge โ€” lower latency, no idle servers to pay for โ€” without touching the part of the stack that works.

The problem is that connecting a Worker directly to Postgres hits a wall almost immediately. A Worker gets 6 simultaneous outgoing connections per invocation, and Workers run in thousands of short-lived isolates spread across Cloudflare network. If every invocation opens a fresh connection to your database, you will exhaust its connection limit within minutes of real traffic.

Hyperdrive exists specifically to fix this. This article covers what it actually does, its real limits, and the trap you will fall into if you leave the default cache settings on without reading the documentation. All numbers are from Cloudflare official documentation, checked as of July 2026.

The problem Hyperdrive solves

Six connections per invocation

Workers cap simultaneous outgoing connections at 6 per invocation. The implication is that a Worker is not a long-lived server process that can hold a connection pool in memory. It is an isolate that spins up per request and disappears, with 128 MB of memory that is not shared across invocations.

Translation: the connection pool that every backend engineer is used to โ€” open 20 connections at boot, reuse them for hours โ€” does not exist here. When traffic arrives from 300-plus cities at once, each isolate that needs the database tries to open its own connection, and Postgres eventually answers with too many connections.

Connection setup costs multiple round trips

Opening a PostgreSQL connection is not one request. It is a TCP handshake, then a TLS handshake, then the Postgres protocol authentication exchange. If your Worker runs at the edge in Bangkok and your database is in another region, every one of those round trips crosses the ocean before the first query even goes out.

Hyperdrive moves that connection setup as close to your Worker as possible, and keeps the pool of real database connections near your database. Worker-to-Hyperdrive setup is fast because it happens within the same location; Hyperdrive-to-database is a warm connection that already exists.

What Hyperdrive actually does

One: edge connection setup

Instead of your Worker completing a handshake across a continent, it completes a handshake with Hyperdrive in the same location. The latency of the setup phase largely disappears.

Two: connection pooling near the database

Hyperdrive maintains a pool in one or more regions closest to your origin database, and caps the number of connections it opens to it: roughly 20 per configuration on the Free plan, roughly 100 on Paid. Notably, Hyperdrive does not limit how many client connections your Workers make to it. You can have as many isolates as you like; they all funnel into a bounded pool.

Cloudflare is honest about one caveat here: Hyperdrive is a distributed system, and if a client cannot reach an existing pool it will establish a new one with its own connection allocation. Actual connection counts may occasionally exceed the listed limits, because the system prioritises availability over strict enforcement. Leave headroom in your Postgres max_connections.

Three: query caching

Hyperdrive parses the database wire protocol to distinguish a mutating query from a non-mutating one, and caches responses only for eligible reads. Defaults are max_age of 60 seconds and stale_while_revalidate of 15 seconds, and you can raise max_age to a maximum of 1 hour. Caching is on by default.

The real limits

Limit Workers Free Workers Paid
Configured databases per account 10 25
Database queries 100,000 / day Unlimited
Origin database connections (per config) ~20 ~100
Initial connection timeout 15 seconds 15 seconds
Idle connection timeout 10 minutes 10 minutes
Maximum query duration 60 seconds 60 seconds
Maximum cached query response 50 MB 50 MB

The one people trip over is 25 configurations per account on Paid. If you want one cached config and one cache-disabled config per database โ€” which you probably do, for reasons covered below โ€” that is two configs per database. Also note that a response larger than 50 MB is not cached, but is still returned to your Worker normally.

Pricing, as of July 2026

Item Workers Free Workers Paid
Database queries via Hyperdrive 100,000 / day (resets 00:00 UTC) Unlimited
Connection pooling Included Included, no additional charge
Query caching Included Included, no additional charge
Egress / data transfer No charge No charge
Do cache hits count as queries Yes Yes (but Paid is unlimited)

In short: on Workers Paid ($5/month), Hyperdrive adds nothing to your bill. You still pay for your Postgres as before, and for Workers as normal. That makes the ROI calculation unusually simple, because the marginal cost of adding Hyperdrive is zero.

A worked example: e-commerce with Postgres already in production

Say you run an online retailer selling into Thailand and the rest of Southeast Asia. Your PostgreSQL sits in ap-southeast-1. The catalog holds 200,000 SKUs. You use PostGIS to find the nearest store to a buyer. Finance has written a pile of long, gnarly SQL reports against it.

Migrating all of this to D1 is a non-starter โ€” PostGIS alone rules it out. But what you do want is product pages rendered from the edge, without moving the database at all.

What you build

You create two Hyperdrive configurations. The first has caching enabled, for reads that tolerate a short stale window: product listings, category pages, search results. The second is created with --caching-disabled, for everything where stale data is a bug: authentication, sessions, permissions, cart contents, inventory counts at checkout, and any read that immediately follows a write.

Bind both to the same Worker, construct a separate database client per binding, and pass the cache-disabled client to your auth and checkout modules while the cached client serves the catalog. This matters especially if an ORM owns your SQL, because the ORM writes the query, not you โ€” the only thing you control is which client it uses.

What you get

Repeated catalog queries are answered from cache at the edge, without a round trip to the database, and the load on Postgres drops correspondingly. Connections are bounded by Hyperdrive during traffic spikes instead of piling up. You did not stand up PgBouncer, you do not operate it, and you do not patch it.

What to watch

If your Worker issues several sequential queries per request, running it at the edge means each query pays a cross-ocean round trip in series. Cloudflare documents the difference bluntly: 20-30 ms per query from a distant region, versus 1-3 ms when the Worker is placed near the database. The fix is Smart Placement โ€” run the Worker close to the database instead of close to the user. But if your Worker makes only one query per request, Placement does not help, because the total round-trip time is the same either way.

The traps you need to know before turning it on

The cache does not invalidate when you write

This is the one that bites teams hardest. Cloudflare documentation is explicit: Hyperdrive does not purge or invalidate cached read query results when your application writes to your database. A later matching SELECT can return the cached result until max_age expires, and can keep serving it during the stale_while_revalidate window while it refreshes in the background.

If you leave caching on at defaults and point it at your permissions table or your session table, you have just created a security hole with a 60-second fuse. Cloudflare guidance is direct: use a cache-disabled configuration for authentication, sessions, permissions, billing state, admin settings, and reads immediately after a write.

Functions like NOW() make a query uncacheable

Hyperdrive only caches queries built from functions PostgreSQL classifies as IMMUTABLE. Functions classified STABLE or VOLATILE โ€” NOW(), CURRENT_DATE, CURRENT_TIMESTAMP, RANDOM(), LASTVAL() โ€” make the whole query uncacheable.

So a dashboard query written as WHERE created_at > NOW() - INTERVAL 1 hour will never be cached, not once. The fix is to compute the timestamp in application code and pass it in as a parameter. And do not write those function names in SQL comments either: Cloudflare warns that its parser uses text pattern matching and may treat a query as uncacheable because of a comment.

Transaction pooling means SET does not persist

Hyperdrive pools in transaction mode. A connection returns to the pool when the transaction completes, and is then RESET. Your SET statements do not carry over to the next query. You must re-issue them per transaction, or bundle the SET into the same query. Cloudflare also explicitly advises against wrapping many operations in one long transaction just to preserve state โ€” doing so pins a connection for the whole duration and defeats the point of pooling.

When a direct connection, or a server in the same region, is the better choice

Hyperdrive is not the right answer for everyone.

If your backend is a long-running server sitting in the same region as your database โ€” an API on ECS or EC2 in ap-southeast-1 โ€” you already have an in-process connection pool and single-digit millisecond latency to the database. Putting Hyperdrive in the middle adds a hop and buys you nothing. Do not do it.

If your application needs long transactions holding SET state, advisory locks, LISTEN/NOTIFY, or prepared statements that must survive across requests, transaction pooling will fight you. This is not a Hyperdrive-specific flaw โ€” it is inherent to every transaction-mode pooler, PgBouncer included โ€” but you need to know it before you commit.

And if your workload is batch work with queries running longer than 60 seconds โ€” ETL, large backfills, heavy reporting โ€” Hyperdrive will terminate them. That work belongs on a server talking to Postgres directly, not in a Worker. We have written more about the boundaries in when not to use Cloudflare Workers, and about how the runtimes compare in Cloudflare Workers vs AWS Lambda.

Summary

Hyperdrive does not magically make your Postgres faster. It removes the two structural reasons Workers cannot talk to a normal database โ€” the 6-connection ceiling and the cost of connection setup โ€” and adds a cache on top. That is enough to move compute to the edge without touching the database, which is exactly what most teams actually want.

Cipher designs and implements systems on the Cloudflare Developer Platform for businesses in Thailand. If you have a PostgreSQL that works and you are trying to decide which parts of your compute should move to Workers, we can assess the architecture and tell you which parts are worth moving and which should stay where they are.

Frequently Asked Questions

Does using Hyperdrive require migrating the database

No. Hyperdrive connects to the PostgreSQL or MySQL database you already run, whether that is RDS, Cloud SQL, Azure Database, or a server you manage yourself. You take your existing connection string, create a configuration, and bind it to your Worker. No schema changes and no dropped extensions.

How much does Hyperdrive cost

As of July 2026, Hyperdrive is included in both the Workers Free and Workers Paid plans. The Free plan caps database queries at 100,000 per day; the Paid plan does not limit query volume. Connection pooling and query caching are included with no additional charge, and Hyperdrive does not charge for egress.

Does the Hyperdrive cache return stale data after a write

Yes. Cloudflare documentation states that Hyperdrive does not purge or invalidate cached read results when your application writes to the database. The defaults are a max_age of 60 seconds and a stale_while_revalidate of 15 seconds. For authentication, sessions, permissions, and reads that immediately follow a write, create a second cache-disabled Hyperdrive configuration and bind it alongside the cached one.

Why is a query containing NOW() never cached

Hyperdrive only caches queries whose functions PostgreSQL classifies as IMMUTABLE. Functions such as NOW(), CURRENT_DATE, and RANDOM() are classified STABLE or VOLATILE and therefore make the query uncacheable. The workaround is to compute the value in application code and pass it in as a query parameter.

Does Hyperdrive actually reduce latency

It does, because connection setup happens near the Worker and the connection pool sits near the database. But if your Worker issues several sequential queries per request, you should also use Placement to run the Worker near the database. Cloudflare documents roughly 20-30 ms of latency per query from a distant region versus 1-3 ms when the Worker is placed nearby.

Scroll to Top