Hyperdrive’s private network path

Hyperdrive, Cloudflare’s connection pooling and caching layer for databases accessed from Workers, now supports sending Postgres traffic through Cloudflare Tunnels. That capability opens a secure path for Workers to reach databases hosted on private networks, rather than exposing those databases to the public Internet. But making Hyperdrive speak Tunnel required a custom transport layer, not just a configuration change.

The core challenge is architectural. Hyperdrive’s Postgres implementation uses a custom handler built directly on the Postgres message protocol. Because Hyperdrive sometimes rewrites specific message types or contents, it needs byte-level control over traffic. That control also means Hyperdrive is not tied to any particular transport library or protocol — a useful property when you need to egress over different types of connections.

In Rust, that flexibility comes from the AsyncRead and AsyncWrite traits defined by the tokio ecosystem. Hyperdrive’s entire custom protocol handler is written against a generic stream using these traits, so it does not need to know whether bytes are flowing over a TCP socket, a TLS connection, or something else entirely. Swapping the transport means only swapping the stream construction; the handler logic stays intact.

WebSocket under the hood

Cloudflare Tunnels handle ingress by speaking WebSocket on both ends. The cloudflared daemon inside your private network takes care of the translation on the database side. On the Hyperdrive side, there was no equivalent translation layer for Postgres messages, so Cloudflare had to build one.

The building blocks were already available. Tungstenite provides WebSocket support in Rust, and to fit WebSocket into Hyperdrive's generic I/O model, it just needed to implement the poll-based functions required by AsyncRead and AsyncWrite. Existing open-source adapters existed, but none satisfied Hyperdrive’s full set of requirements: AsyncRead, AsyncWrite, Send, Sync, and Unpin. Hyperdrive operates across multiple threads on the tokio runtime, and all five traits matter there.

Translation turned out to be mostly mechanical. The WebSocket library bases its API on the Sink and Stream traits, and there is significant overlap with the AsyncWrite contract. For instance, poll_flush and poll_shutdown map almost one-to-one from their Sink equivalents, needing minimal engineering effort. The result is a wrapper that lets a WebSocket connection opened toward a Tunnel behave like any other transport stream in Hyperdrive, with no special-casing in the broader codebase.

Connecting through a Tunnel then becomes a stream transformation sequence: establish an SslStream to the Tunnel hostname, perform an HTTP upgrade to WebSocket, and hand the resulting connection to Hyperdrive’s generic handler.

Authentication at the edge

The WebSocket upgrade request carries more than just routing information. Tunnels are protected by Cloudflare’s secure defaults and defense-in-depth principles, and Cloudflare recommends configuring a Zero Trust Access Application for any Tunnel used with Hyperdrive. These applications should rely on Service Tokens to authorize connections.

When you create a new Hyperdrive, you can supply a Service Token’s ID and Secret, which Cloudflare encrypts and stores with the database configuration. Hyperdrive sends credentials in the request headers during the WebSocket upgrade, so only authorized traffic gets through the Tunnel and reaches your database. The request includes:

json { "headers": { "CF-Access-Client-Id": "your-service-token-id", "CF-Access-Client-Secret": "your-service-token-secret" } }

Postgres has its own access controls, but with Service Token authentication at the Tunnel boundary, unwanted traffic does not get a chance to reach your private network in the first place. That separation — keep the database private, authenticate at the edge, let Hyperdrive handle the pooling and caching — is what makes the connection between Workers and private databases practical at scale.

Eating our own dogfood

For Cloudflare’s internal teams, Hyperdrive’s value proposition is immediate: nearly every product stores its control plane state in centrally run Postgres clusters. Services elsewhere in the network have historically used a push-based model to publish updates to Quicksilver and had to work through the inherent complexities of that approach. Tunnel integration directly addresses that recurring challenge.

When we started exploring Tunnel support, internal teams were quick to voice interest. That made them ideal early testers — getting fast feedback, improving reliability, and building stronger cross-team connections before a public release. Being “customer zero” is a key part of how we ship better products.

During the rollout of early Tunnel integration versions, we gave internal teams access and worked with them to fix rough edges as they surfaced. That first batch has since built new or refactored products on Hyperdrive over Tunnels. Two early production use cases you may have already encountered: Workers Builds and the abuse reporting flow. More teams are currently onboarding.

Why Rust made this easy

Our goal with Hyperdrive is to let Workers connect to centralized databases quickly and consistently, especially when the database is inside a virtual private cloud (VPC) with no public exposure. To do that, we built on top of our Zero Trust tools rather than inventing a new access mechanism.

One unexpected advantage: implementing the Tunnel client in our runtime was straightforward thanks to Rust’s trait system. The extensibility it provides meant we could integrate the new connection path cleanly without restructuring existing code.

The feature is already in production within Cloudflare, solving historical problems for multiple teams. If you want to try it yourself, the setup guide is available — Hyperdrive over a Tunnel connects your Worker to a private database without opening it up to the public internet.