MySQL support reaches GA
Hyperdrive, Cloudflare's database connection pooler for Workers, now supports MySQL at general availability. The product previously handled only Postgres, and a beta for the MySQL protocol was announced last year. The gap between beta and GA came down to roughly 20 bug fixes, many of which surfaced in real customer traffic.
Hyperdrive holds warm SQL connections open across Cloudflare's network and shares them among Worker requests. Opening a fresh connection to a SQL database costs at least five network round trips, which is wasteful on a serverless platform, and large connection counts carry resource costs even though MySQL — unlike Postgres — does not tie up an entire OS process per connection. Caching is Hyperdrive's other lever: common queries can be served from the global CDN cache, cutting latencies and origin load.
Encoding issues in the early beta
The first batch of fixes was straightforward once reported. One early report involved emojis that were written to the database but not returned correctly. During the startup handshake, Hyperdrive negotiates connection encoding, and it was negotiating utf8 — a deprecated alias for utf8mb3, whose 1–3 bytes per Unicode code point cannot represent all of UTF-8. Switching the handshake to utf8mb4 resolved it.
A second encoding fault came from COM_RESET_CONNECTION, the lightweight command Hyperdrive uses to clear session state between checkouts. That reset discards the character set negotiated at startup and reverts the connection to the server default, so on an instance defaulting to latin1, a previously utf8mb4 connection came back as latin1. The fix: issue a command setting the encoding to utf8mb4 after every reset.
The case of the vanished rows
The most difficult defect was reported by Hyperdrive's highest-volume MySQL customer during the beta: occasional empty responses where non-empty results were expected, occurring in roughly 0.001% of cases. The team sifted through telemetry, reviewed the customer's logic, raised the trace rate for the affected Hyperdrive instance, and ruled out network faults, but traces at that failure rate were nearly impossible to capture. The one useful signal was that it only ever happened on instances with caching enabled, pointing at the MySQL caching path.
Where cache lives in Hyperdrive's topology
Each Hyperdrive instance runs as two nodes. The Client node sits on the same machine as the Worker, serves local cache reads when enabled, and forwards whatever it cannot handle. The Endpoint node, placed in the data center nearest the origin database, owns the connection pool. Both use the CDN cache of the data center they run in, so when the two nodes are co-located they share one cache.


That sharing is usually a performance win. Cache keys are derived from a hash of the query's wire messages with some normalization, and the resulting bytes are stored. A Client co-located with an Endpoint can therefore answer a request straight from the shared cache when the Endpoint has recently cached the same query. The scheme only holds up if identical bytes represent identical responses regardless of which node wrote them.
Two sets of capabilities
With no direct trace available, the team went back to the MySQL client/server protocol to check for assumptions carried over from the Postgres implementation.

The protocol begins with a Connection Phase, in which client and server agree on authentication and capabilities, followed by a Command Phase, in which the client issues statements and waits for responses. Capabilities act as feature flags for backwards-compatible protocol evolution, and a mismatch in what each side believes the other supports can desync the connection.
Hyperdrive sits on both sides of that negotiation: it is a client to the origin database and a server to the Worker. To parse messages coming back from the origin, it uses a fixed set of capability flags, which may differ from the Worker's set. Every origin response must therefore be translated into the capabilities the Worker's driver expects.
One such capability is CLIENT_DEPRECATE_EOF, which changes how result sets terminate: without it, the server sends an EOF packet between column definitions and rows plus a final EOF; with it, the metadata EOF is dropped and the final EOF becomes an OK packet. MySQL server 5.7.5 and later supports the capability, but the newer behavior applies only when the client negotiates it, and the popular Node.js driver mysql2 does not currently support it. Hyperdrive does, so it rewrites result sets to insert EOFs and converts OK packets to EOFs when the Worker's driver requires them.

The faulty assumption
Sorting through telemetry, documentation and code finally exposed the root cause: a Postgres-era assumption in the Client caching logic. With Postgres' wire protocol it was reasonable to cache exactly the bytes written back to the Worker. MySQL breaks that, because Client-written bytes are translated for the Worker's capabilities while the Endpoint could only ever emit Hyperdrive-capability bytes. Two nodes sharing a cache could therefore hand each other responses in the wrong format.
That explains the empty results and hangs, but only when Client and Endpoint share a data center and one reads a value cached by the other. Two orderings are possible.
Endpoint writes, Client reads:
- While serving query Q, the Endpoint receives response R from the origin and caches its result bytes encoded with Hyperdrive's capabilities.
- A Client handling another request for Q finds those bytes in the shared cache.
- The Client returns them to the Worker without translating to the Worker's capabilities.

Client writes, Endpoint reads:
- After finishing a request for Q, the Client writes response bytes translated for the Worker's capabilities into the cache.
- An Endpoint serving Q finds them there.
- The Endpoint sends those bytes onward to a different Client, which tries to translate them again and emits an early EOF or hangs.

The fix and what comes next
The remedy follows directly from the diagnosis: the cache now always stores a canonical form of the query result bytes, encoded with Hyperdrive's capabilities, no matter which node performed the write. Since that change shipped, empty-row responses have disappeared and the success rate for Client connections has reached 99.99%.
MySQL support for Hyperdrive is available now. A Hyperdrive instance can be created against an existing MySQL-compatible database through the dashboard or wrangler, or pointed at a new PlanetScale database.
npx wrangler hyperdrive create HYPERDRIVE_NAME --connection-string="mysql://user:[email protected]:3306/dbname"


