WorkersでMySQLがさらに進化!Cloudflare Hyperdrive徹底検証(公開DB・プライベートDB接続)

はじめに
※PostgreSQLは元々サポートされていました。
Cloudflare blog:https://blog.cloudflare.com/building-global-mysql-apps-with-cloudflare-workers-and-hyperdrive/
Hyperdriveについては検証をしていなかったので、この機会にドキュメントを確認していたところ、ベータ版ですがプライベート環境のデータベースにも接続ができる機能がありました。
Cloudflare doc:https://developers.cloudflare.com/hyperdrive/configuration/connect-to-private-database/
基本的にDBはプライベート環境にあるため、こういった要件もあるかと思いましたので、この機会に試してみました。
Hyperdriveについて
接続を高速化させるためにコネクションなどの再利用や、読み取り用のクエリをキャッシュさせたりすることができます。
公式ドキュメントにHyperdriveの仕組みについての解説がありますので参考にしてください。
Cloudflare Doc:https://developers.cloudflare.com/hyperdrive/configuration/how-hyperdrive-works/
動作検証
・Cloudflare Hyperdriveを使用したMySQLサーバ接続
・Hyperdriveキャッシュテスト
・プライベートDB接続
Cloudflare Hyperdriveを使用したMySQLサーバ接続
以下の構成で検証をしてみます。

サーバ準備
まず外部から接続できるMySQLサーバを用意します。OSはUbuntu 24.04を使用して検証します。
基本的なMySQLの設定についてはここでは触れませんので、他サイトなどを参考にしてください。
MySQLのバージョンは以下を使用しました。
$ mysql --version
mysql Ver 8.4.5 for Linux on x86_64 (MySQL Community Server - GPL)
Firewall設定
FirewallなどでMySQLポート(3306)を開放します。
Cloudflareから接続することになるので、許可IPとしてCloudflareのIPを設定します。
Cloudflareからの接続IP範囲は以下に公式情報があります。
Cloudflare IP範囲:https://www.cloudflare.com/ja-jp/ips/

MySQL設定
localhost以外からも接続できるように`mysqld.cnf`の`bind-address`を変更して、mysqlをrestartします。
$ vi /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 0.0.0.0
$ systemctl restart mysql
DB接続用のユーザを作成します。
権限などはそれぞれの環境に合わせてください。
CREATE USER 'test-user-001'@'%' IDENTIFIED BY 'パスワード';
GRANT ALL PRIVILEGES ON *.* TO 'test-user-001'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
DBとTABLEを作成して、適当なデータを入れておきます。
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE test01 (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
hometown VARCHAR(100),
create_date DATETIME DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO test01(name, hometown) VALUES('与太郎', '江戸');
INSERT INTO test01(name, hometown) VALUES('若旦那' , '京都');
INSERT INTO test01(name, hometown) VALUES('お松', '大坂');
Hyperdrive準備
wranglerコマンドでCloudflareにログインしておきます。
$ npx wrangler login
以下コマンドでHyperdriveを作成します。
$ npx wrangler hyperdrive create test-hyperdrive --connection-string="mysql://test-user-001:パスワード@mysqlサーバの外部IP:3306/testdb" --caching-disabled
パスワードにエスケープしなければいけない文字が入ってる場合は、「\」でエスケープしてください。
また、ここではHyperdriveのcache機能はdisableにしてます。(--caching-disabled)
エラーにならなければ、以下のようにCloudflareの画面からHyperdriveの確認ができます。

以下コマンド、もしくはCloudflareの画面からHyperdriveのIDをメモしておきます。
$ npx wrangler hyperdrive list

Workers準備
以下コマンドでCloudflare Workersを作成して、作成されたディレクトリに移動します。
$ npm create cloudflare@latest -- test-hyperdrive-01
$ cd test-hyperdrive-01
選択する項目としては以下を設定しました。
・Hello World example
・typescript
`wrangler.jsonc`を編集して、以下を追加します。
・compatibility_flags
・hyperdrive(id部分は、上記でメモしたHyperdriveのIDを指定してください。)
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "test-hyperdrive-01",
"main": "src/index.ts",
"compatibility_flags": ["nodejs_compat"],
"compatibility_date": "2025-07-24",
"observability": {
"enabled": true
},
"hyperdrive": [
{
"binding": "HYPERDRIVE",
"id": "xxxxxxxxxxxxx"
}
]
}MySQLに接続するためのパッケージをインストールします。
今回はDrizzle ORMを使用して接続させてみようと思いますので、以下コマンドを実行します。
$ npm i drizzle-orm mysql2 dotenv
$ npm i -D drizzle-kit tsx @types/node
Drizzle ORMを使用しなくても接続できますので、その場合は以下などを参照してください。
Cloudflare Doc:https://developers.cloudflare.com/hyperdrive/examples/connect-to-mysql/mysql-drivers-and-libraries/mysql2/
`src/db/schema.ts`を作成します。
import { mysqlTable, int, varchar, timestamp } from 'drizzle-orm/mysql-core';
export const test01Table = mysqlTable('test01', {
id: int('id').primaryKey().autoincrement(),
name: varchar('name', { length: 255 }).notNull(),
hometown: varchar('hometown', { length: 255 }).notNull().unique(),
createDate: timestamp('create_date').defaultNow(),
});`src/index.ts`を編集します。
import { drizzle } from 'drizzle-orm/mysql2';
import { createConnection } from 'mysql2';
import { test01Table } from './db/schema';
export interface Env {
HYPERDRIVE: Hyperdrive;
}
export default {
async fetch(request, env, ctx): Promise {
const connection = await createConnection({
host: env.HYPERDRIVE.host,
user: env.HYPERDRIVE.user,
password: env.HYPERDRIVE.password,
database: env.HYPERDRIVE.database,
port: env.HYPERDRIVE.port,
disableEval: true,
});
const db = drizzle(connection);
const allUsers = await db.select().from(test01Table);
return Response.json(allUsers);
},
} satisfies ExportedHandler<Env>; 上記で準備ができたので、デプロイします。
$ npx wrangler deploy
デプロイしたWorkersの開発用のURL(xxx.workers.dev)にアクセスします。
$ curl -k https://test-hyperdrive-01.xxx.workers.dev | jq .
[
{
"id": 1,
"name": "与太郎",
"hometown": "江戸",
"createDate": "2025-07-27T11:49:47.000Z"
},
{
"id": 2,
"name": "若旦那",
"hometown": "京都",
"createDate": "2025-07-27T11:49:47.000Z"
},
{
"id": 3,
"name": "お松",
"hometown": "大坂",
"createDate": "2025-07-27T11:49:48.000Z"
}
]
Cloudflare Workers経由でMySQLに登録したデータを取得することができました。
Hyperdriveキャッシュテスト
まず、データが少ないと確認できないため、テーブルにデータを1万行追加しておきます。
10回curlでリクエストを行うスクリプト(curl-check.sh)を作成します。
#!/bin/zsh
for i in {0..10}
do
curl -k https://test-hyperdrive-01.xxxxx.workers.dev -o /dev/null -w"time_totalt%{time_total}n"
done
上記スクリプトの実行結果をファイルに保存します。
./curl-check.sh > non-cache.log
次にHyperdriveのキャッシュを有効にして検証してみます。
以下コマンドを実行してキャッシュを有効化します。
$ npx wrangler hyperdrive update HyperdriveのID --caching-disabled false --max-age 30 --swr 0
画面から確認すると以下のようになってます。

スクリプトを先程のファイル名とは別にして保存する形で実行します。
./curl-check.sh > cache.log
結果は以下のようになり、キャッシュされるためSELECTが重い処理の場合は有効性が確認できました。


Hyperdriveの画面からキャッシュを返したのか、直接返したのかを確認することができます。

キャッシュの仕組みなどについて
キャッシュの仕組みは以下のドキュメントに載っていますのでご確認ください。
Cloudflare Doc:https://developers.cloudflare.com/hyperdrive/configuration/query-caching/
INSERT、UPSERT、CREATE TABLE、または以下で指定されているクエリはキャッシュされない仕様になっているそうです。
https://www.postgresql.org/docs/current/xfunc-volatility.html
検証していて気づいたのですが、どのクエリがキャッシュされてるのかなどの情報は、分析画面や、レスポンスヘッダからは今のところ確認できなさそうです。
GraphQLからHyperdriveの情報が取得できますが、分析画面の情報を取得するように見えますので、それ以外の情報は取得できなさそうです。
Cloudflare Doc:https://developers.cloudflare.com/hyperdrive/observability/metrics/
キャッシュのパージについても記載がないので、できなさそうです。
上記のことから、キャッシュ自体はWorkersで行ったほうが制御しやすいので良いかと思います。
もちろんWorkersとHyperdriveで多段キャッシュにすることで効果を得られるケースもあると思います。しかしHyperdriveのキャッシュを使用する際にはよく検討する必要があると思います。
プライベートDB接続
以下の構成で検証をしていきます。

Firewall設定
プライベート環境にするために、CloudflareのIPだけを通すFirewallの設定を削除して、外部からアクセスできないように変更します。

注意事項
スーパーボットファイトモードを使用している場合は、「Definitely Automated」を「Allow」に設定しないと、トンネルがwebsocket: bad handshakeエラーで失敗する可能性があるそうなので、設定を変更しておきます。
Cloudflare Doc:https://developers.cloudflare.com/hyperdrive/configuration/connect-to-private-database/#before-you-start
トンネル作成
CloudflareのメニューからZero Trustをクリックします。

Tunnels -> 「トンネルを作成する」を選択します。

「Cloudflared」を選択します。

トンネル名に分かりやすい任意の値を入力して「トンネルを保存」をクリックします。

今回はUbuntuサーバにMySQLをインストールしましたので、「Debian」を選択して画面に記載してあるとおりにCloudflaredをインストールします。

インストールが完了してトンネルを実行すると以下のように「接続済」ステータスが出てきます。
そうしたら「次へ」をクリックします。

MySQLに接続するためのパブリックホスト名の設定をします。
サブドメインは任意の値を設定します。
※自動的にCloudflareのDNSに登録されます。
サービスは`TCP://localhost:3306`を設定して、「セットアップを完了する」をクリックします。

正常に完了すればトンネルが作成されます。

また、DNSにパブリックホスト名で指定したレコードが追加されます。

Hyperdriveの作成
次にHyperdriveを作成します。
Hyperdriveの画面から「Create Configuration」をクリックします。

以下のようにプライベートデータベースをMySQLで設定をします。
接続ユーザやパスワードはMySQLの設定に合わせて入力してください。
すべて入力したら「作成」をクリックします。


正常に完了すればHyperdriveが作成されます。

Workers準備
以下のコマンドでCloudflare Workersを作成して、作成されたディレクトリに移動します。
$ npm create cloudflare@latest -- test-hyperdrive-02
$ cd test-hyperdrive-02
選択する項目としては以下を設定しました。
・Hello World example
・typescript
`wrangler.jsonc`を編集して、以下を追加します。
・compatibility_flags
・hyperdrive
(id部分は、上記でメモしたプライベートDB用のHyperdriveのIDを指定してください。)
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "test-hyperdrive-02",
"main": "src/index.ts",
"compatibility_flags": ["nodejs_compat"],
"compatibility_date": "2025-07-24",
"observability": {
"enabled": true
},
"hyperdrive": [
{
"binding": "HYPERDRIVE",
"id": "xxxxxxxxxxxxx"
}
]
}後は、「Cloudflare Hyperdriveを使用したMySQLサーバ接続」で書いたコードと同じものを設定します。
・パッケージインストール
・`src/index.ts`
・`src/db/schema.ts`
上記で準備ができたので、デプロイします。
$ npx wrangler deploy
デプロイしたWorkersの開発用のURL(xxx.workers.dev)にアクセスしてみます。
$ curl -k https://test-hyperdrive-02.xxx.workers.dev | jq .
[
{
"id": 1,
"name": "与太郎",
"hometown": "江戸",
"createDate": "2025-07-27T11:49:47.000Z"
},
{
"id": 2,
"name": "若旦那",
"hometown": "京都",
"createDate": "2025-07-27T11:49:47.000Z"
},
{
"id": 3,
"name": "お松",
"hometown": "大坂",
"createDate": "2025-07-27T11:49:48.000Z"
},
......
Cloudflare Workers経由でプライベート環境のMySQLに登録したデータを取得することができました。
統計情報画面
Hyperdriveの画面から統計情報を確認する事ができます。
シンプルな画面となっており、現状のHyperdriveの使用状況の参考として確認ができます。

注意事項
以下のドキュメントに、PostgreSQLとMySQLにおけるHyperdriveのサポート外の内容が記載されています。
Cloudflare doc:https://developers.cloudflare.com/hyperdrive/reference/supported-databases-and-features/#unsupported-postgresql-features
使用する前に一度確認しておくことをおすすめいたします。
最後に
Workersから今まで使用していたDBサーバに接続して使用できるため、これまでのデータやDB操作をそのまま使えます。
Hyperdriveの設定は特に難しくなく、Workersからの接続もシンプルに設定できたのは良かったです。
気になった点としてはキャッシュ機能ですが、個人的にはWorkers側で制御した方がシンプルで良いと感じました。この点は今後のアップデートで改善されることを期待します。
そしてCloudflareなら上記以外でも、
・パフォーマンスの向上
・サイトの信頼性の向上
・セキュリティの向上
が、一つのサービスで実現できますので非常におすすめです。
Cloudflareに、アクセリアの運用サポートをプラスしたCDNサービスを提供しています
移行支援によるスムーズな導入とともに、お客様の運用負担を最小限にとどめながら、WEBサイトのパフォーマンスとセキュリティを最大限に高めます。運用サポートはフルアウトソーシングからミニマムサポートまで、ご要望に合わせてご提供します。
Cloudflare(クラウドフレア)の導入や運用について、またそれ以外のことでもなにか気になることがございましたらお気軽にご相談下さい。
サービスにご興味をお持ちの方は
お気軽にお問い合わせください。
Webからお問い合わせ
お問い合わせお電話からお問い合わせ
平日09:30 〜 18:00
Free Service












