mcpField
C
cloudflare-hyperdrive

cloudflare-hyperdrive

github.com/jackspaceクラウド・DevOps1642 回インストール12 週間前に更新
リポジトリ

cloudflare-hyperdrive について

Hyperdrive を介して Cloudflare Workers と既存の PostgreSQL または MySQL データベースを接続するためのセットアップ・利用ガイドです。バインディング、データベースドライバー、接続方式、ORM、ローカル開発を扱います。

主な機能

  1. 01Hyperdrive 設定の作成
  2. 02Worker バインディングの設定
  3. 03PostgreSQL と MySQL の接続
  4. 04コネクションプールとクエリキャッシュ
  5. 05Drizzle ORM と Prisma の連携
  6. 06ローカルデータベース開発の設定

活用シーン

  1. 01Worker を既存の PostgreSQL データベースに接続
  2. 02Worker を既存の MySQL データベースに接続
  3. 03ドライバーと接続方式の選択
  4. 04ローカル環境でのデータベース開発

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jackspace/claudeskillz --skill cloudflare-hyperdrive

インストール後、Claude Code で/cloudflare-hyperdriveを入力して読み込まれたか確認します。

同梱ファイルREADME.mdSKILL.json

詳細

Cloudflare Hyperdrive

ステータス:本番環境で使用可能 ✅ 最終更新日:2025-10-22 依存関係:cloudflare-worker-base(Worker のセットアップに推奨) 最新バージョン:[email protected]+、[email protected]+、[email protected]+、[email protected]+


クイックスタート(5 分)

1. Hyperdrive の設定を作成する
# For PostgreSQL
npx wrangler hyperdrive create my-postgres-db \
  --connection-string="postgres://user:[email protected]:5432/database"

# For MySQL
npx wrangler hyperdrive create my-mysql-db \
  --connection-string="mysql://user:[email protected]:3306/database"

# Output:
# ✅ Successfully created Hyperdrive configuration
#
# [[hyperdrive]]
# binding = "HYPERDRIVE"
# id = "a76a99bc-7901-48c9-9c15-c4b11b559606"

id の値を保存してください。次の手順で必要になります。


2. wrangler.jsonc でバインディングを設定する

wrangler.jsonc に追加します。

{
  "name": "my-worker",
  "main": "src/index.ts",
  "compatibility_date": "2024-09-23",
  "compatibility_flags": ["nodejs_compat"],  // REQUIRED for database drivers
  "hyperdrive": [
    {
      "binding": "HYPERDRIVE",                     // Available as env.HYPERDRIVE
      "id": "a76a99bc-7901-48c9-9c15-c4b11b559606"  // From wrangler hyperdrive create
    }
  ]
}

重要:

  • すべてのデータベースドライバーで nodejs_compat フラグが必須です
  • binding はコード内で Hyperdrive にアクセスするための名前です(env.HYPERDRIVE)
  • id は Hyperdrive 設定 ID です(データベース ID ではありません)

3. データベースドライバーをインストールする
# For PostgreSQL (choose one)
npm install pg           # node-postgres (most common)
npm install postgres     # postgres.js (modern, minimum v3.4.5)

# For MySQL
npm install mysql2       # mysql2 (minimum v3.13.0)

4. データベースにクエリを実行する

node-postgres(pg)を使用する PostgreSQL:

import { Client } from "pg";

type Bindings = {
  HYPERDRIVE: Hyperdrive;
};

export default {
  async fetch(request: Request, env: Bindings, ctx: ExecutionContext) {
    const client = new Client({
      connectionString: env.HYPERDRIVE.connectionString
    });

    await client.connect();

    try {
      const result = await client.query('SELECT * FROM users LIMIT 10');
      return Response.json({ users: result.rows });
    } finally {
      // Clean up connection AFTER response is sent
      ctx.waitUntil(client.end());
    }
  }
};

mysql2 を使用する MySQL:

import { createConnection } from "mysql2/promise";

export default {
  async fetch(request: Request, env: Bindings, ctx: ExecutionContext) {
    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  // REQUIRED for Workers (eval() not supported)
    });

    try {
      const [rows] = await connection.query('SELECT * FROM users LIMIT 10');
      return Response.json({ users: rows });
    } finally {
      ctx.waitUntil(connection.end());
    }
  }
};

5. デプロイする
npx wrangler deploy

これで完了です。 Worker は Hyperdrive 経由で既存のデータベースに接続し、次の機能を利用できます。

  • ✅ グローバルなコネクションプーリング
  • ✅ クエリの自動キャッシュ
  • ✅ レイテンシの低減(7 回のラウンドトリップを排除)

Hyperdrive の仕組み

問題点

Cloudflare の 300 か所以上のグローバルロケーションから従来型データベースに接続する場合、次の課題があります。

  1. 高レイテンシ — 接続ごとに複数回のラウンドトリップが発生します。

    • TCP ハンドシェイク(1 回のラウンドトリップ)
    • TLS ネゴシエーション(3 回のラウンドトリップ)
    • データベース認証(3 回のラウンドトリップ)
    • 合計:クエリを送信する前に 7 回のラウンドトリップが発生します
  2. 接続数の上限 — 従来型データベースが処理できる同時接続数には限りがあり、分散トラフィックによって簡単に上限に達します。

解決策

Hyperdrive は次の方法でこれらの問題を解決します。

  1. エッジでの接続確立 — 接続ハンドシェイクを Worker の近くで行います(低レイテンシ)
  2. コネクションプーリング — データベースの近くにあるプールで接続を再利用し、ラウンドトリップを排除します
  3. クエリキャッシュ — よく使われるクエリをエッジでキャッシュし、データベースの負荷を軽減します

結果:単一リージョンのデータベースでも、グローバルに分散しているかのように利用できます。


セットアップの全手順

手順 1:前提条件

必要なもの:

  • Workers を利用できる Cloudflare アカウント
  • 既存の PostgreSQL(v9.0-17.x)または MySQL(v5.7-8.x)データベース
  • 次のいずれかを経由してアクセスできるデータベース:
    • パブリックインターネット(TLS/SSL が有効)、または
    • プライベートネットワーク(Cloudflare Tunnel 経由)

重要:Hyperdrive にはTLS/SSL が必須です。データベースの暗号化が有効になっていることを確認してください。


手順 2:Hyperdrive の設定を作成する

方法 A:Wrangler CLI(推奨)

# PostgreSQL connection string format:
# postgres://username:password@hostname:port/database_name

npx wrangler hyperdrive create my-hyperdrive \
  --connection-string="postgres://myuser:[email protected]:5432/mydb"

# MySQL connection string format:
# mysql://username:password@hostname:port/database_name

npx wrangler hyperdrive create my-hyperdrive \
  --connection-string="mysql://myuser:[email protected]:3306/mydb"

方法 B:Cloudflare ダッシュボード

  1. Hyperdrive ダッシュボードに移動します
  2. Create Configuration をクリックします
  3. 接続情報を入力します。
    • 名前:my-hyperdrive
    • プロトコル:PostgreSQL または MySQL
    • ホスト:db.example.com
    • ポート:5432(PostgreSQL)または 3306(MySQL)
    • データベース:mydb
    • ユーザー名:myuser
    • パスワード:mypassword
  4. Create をクリックします

接続文字列の形式:

# PostgreSQL (standard)
postgres://user:password@host:5432/database

# PostgreSQL with SSL mode
postgres://user:password@host:5432/database?sslmode=require

# MySQL
mysql://user:password@host:3306/database

# With special characters in password (URL encode)
postgres://user:p%40ssw%24rd@host:5432/database  # p@ssw$rd

手順 3:Worker のバインディングを設定する

wrangler.jsonc に Hyperdrive バインディングを追加します。

{
  "name": "my-worker",
  "main": "src/index.ts",
  "compatibility_date": "2024-09-23",
  "compatibility_flags": ["nodejs_compat"],
  "hyperdrive": [
    {
      "binding": "HYPERDRIVE",
      "id": "<your-hyperdrive-id-here>"
    }
  ]
}

複数の Hyperdrive 設定:

{
  "hyperdrive": [
    {
      "binding": "POSTGRES_DB",
      "id": "postgres-hyperdrive-id"
    },
    {
      "binding": "MYSQL_DB",
      "id": "mysql-hyperdrive-id"
    }
  ]
}

Worker でのアクセス方法:

type Bindings = {
  POSTGRES_DB: Hyperdrive;
  MYSQL_DB: Hyperdrive;
};

export default {
  async fetch(request, env: Bindings, ctx) {
    // Access different databases
    const pgClient = new Client({ connectionString: env.POSTGRES_DB.connectionString });
    const mysqlConn = await createConnection({ host: env.MYSQL_DB.host, ... });
  }
};

手順 4:データベースドライバーをインストールする

PostgreSQL ドライバー:

# Option 1: node-postgres (pg) - Most popular
npm install pg
npm install @types/pg  # TypeScript types

# Option 2: postgres.js - Modern, faster (minimum v3.4.5)
npm install postgres@^3.4.5

MySQL ドライバー:

# mysql2 (minimum v3.13.0)
npm install mysql2

ドライバーの比較:

ドライバーデータベースメリットデメリット最小バージョン
pgPostgreSQL最も普及しており、安定していて、ドキュメントが充実していますpostgres.js よりわずかに低速です8.13.0+
postgresPostgreSQL高速で、モダンな API を備え、ストリーミングをサポートします新しいため、コミュニティの例が少なめです3.4.5+
mysql2MySQLPromise、プリペアドステートメントに対応し、高速ですWorkers では disableEval: true が必要です3.13.0+

手順 5:Worker でドライバーを使用する

pg を使用する PostgreSQL(Client):

import { Client } from "pg";

export default {
  async fetch(request: Request, env: { HYPERDRIVE: Hyperdrive }, ctx: ExecutionContext) {
    // Create client for this request
    const client = new Client({
      connectionString: env.HYPERDRIVE.connectionString
    });

    await client.connect();

    try {
      // Run query
      const result = await client.query('SELECT $1::text as message', ['Hello from Hyperdrive!']);
      return Response.json(result.rows);
    } catch (error) {
      return new Response(`Database error: ${error.message}`, { status: 500 });
    } finally {
      // CRITICAL: Clean up connection after response
      ctx.waitUntil(client.end());
    }
  }
};

pg を使用する PostgreSQL(並列クエリ用の Pool):

import { Pool } from "pg";

export default {
  async fetch(request: Request, env: { HYPERDRIVE: Hyperdrive }, ctx: ExecutionContext) {
    // Create pool (max 5 to stay within Workers' 6 connection limit)
    const pool = new Pool({
      connectionString: env.HYPERDRIVE.connectionString,
      max: 5  // CRITICAL: Workers limit is 6 concurrent external connections
    });

    try {
      // Run parallel queries
      const [users, posts] = await Promise.all([
        pool.query('SELECT * FROM users LIMIT 10'),
        pool.query('SELECT * FROM posts LIMIT 10')
      ]);

      return Response.json({
        users: users.rows,
        posts: posts.rows
      });
    } finally {
      ctx.waitUntil(pool.end());
    }
  }
};

postgres.js を使用する PostgreSQL:

import postgres from "postgres";

export default {
  async fetch(request: Request, env: { HYPERDRIVE: Hyperdrive }, ctx: ExecutionContext) {
    const sql = postgres(env.HYPERDRIVE.connectionString, {
      max: 5,              // Max 5 connections (Workers limit: 6)
      fetch_types: false,  // Disable if not using array types (reduces latency)
      prepare: true        // CRITICAL: Enable prepared statements for caching
    });

    try {
      const users = await sql`SELECT * FROM users LIMIT 10`;
      return Response.json({ users });
    } finally {
      ctx.waitUntil(sql.end({ timeout: 5 }));
    }
  }
};

mysql2 を使用する MySQL:

import { createConnection } from "mysql2/promise";

export default {
  async fetch(request: Request, env: { HYPERDRIVE: Hyperdrive }, ctx: ExecutionContext) {
    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  // REQUIRED: eval() not supported in Workers
    });

    try {
      const [rows] = await connection.query('SELECT * FROM users LIMIT 10');
      return Response.json({ users: rows });
    } finally {
      ctx.waitUntil(connection.end());
    }
  }
};

接続パターン

パターン 1:単一接続(pg.Client)

使用する場面:シンプルなクエリ、リクエストごとに 1 つのクエリ

import { Client } from "pg";

const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
await client.connect();
const result = await client.query('SELECT ...');
ctx.waitUntil(client.end());

利点:シンプルで分かりやすい 欠点:並列クエリを実行できません


パターン 2:コネクションプール(pg.Pool)

使用する場面:1 つのリクエストで複数のクエリを並列実行する場合

import { Pool } from "pg";

const pool = new Pool({
  connectionString: env.HYPERDRIVE.connectionString,
  max: 5  // CRITICAL: Stay within Workers' 6 connection limit
});

const [result1, result2] = await Promise.all([
  pool.query('SELECT ...'),
  pool.query('SELECT ...')
]);

ctx.waitUntil(pool.end());

利点:並列クエリに対応し、パフォーマンスが向上します 欠点:最大接続数を管理する必要があります


パターン 3:接続のクリーンアップ

重要:レスポンスの送信後に接続をクリーンアップするには、必ず ctx.waitUntil() を使用してください。

export default {
  async fetch(request, env, ctx) {
    const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
    await client.connect();

    try {
      const result = await client.query('SELECT ...');
      return Response.json(result.rows);  // Response sent here
    } finally {
      // This runs AFTER response is sent (non-blocking)
      ctx.waitUntil(client.end());
    }
  }
};

ctx.waitUntil() を使う理由

  • Worker がすぐにレスポンスを返せるようになります
  • 接続のクリーンアップはバックグラウンドで行われます
  • 接続リークを防止します

次のようにしないでください。

await client.end();  // ❌ Blocks response, adds latency

ORM との統合

Drizzle ORM(PostgreSQL)

1. 依存関係をインストールします。

npm install drizzle-orm postgres dotenv
npm install -D drizzle-kit

2. スキーマを定義します(src/db/schema.ts)。

import { pgTable, serial, varchar, timestamp } from "drizzle-orm/pg-core";

export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  name: varchar("name", { length: 255 }).notNull(),
  email: varchar("email", { length: 255 }).notNull().unique(),
  createdAt: timestamp("created_at").defaultNow(),
});

3. Worker で使用します。

import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import { users } from "./db/schema";

export default {
  async fetch(request, env: { HYPERDRIVE: Hyperdrive }, ctx) {
    const sql = postgres(env.HYPERDRIVE.connectionString, { max: 5 });
    const db = drizzle(sql);

    const allUsers = await db.select().from(users);

    ctx.waitUntil(sql.end());
    return Response.json({ users: allUsers });
  }
};

Prisma ORM(PostgreSQL)

1. 依存関係をインストールします。

npm install prisma @prisma/client
npm install pg @prisma/adapter-pg

2. Prisma を初期化します。

npx prisma init

3. スキーマを定義します(prisma/schema.prisma)。

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["driverAdapters"]
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id        Int      @id @default(autoincrement())
  name      String
  email     String   @unique
  createdAt DateTime @default(now())
}

4. Prisma Client を生成します。

npx prisma generate --no-engine

5. Worker で使用します。

import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "@prisma/client";
import { Pool } from "pg";

export default {
  async fetch(request, env: { HYPERDRIVE: Hyperdrive }, ctx) {
    // Create driver adapter with Hyperdrive connection
    const pool = new Pool({ connectionString: env.HYPERDRIVE.connectionString, max: 5 });
    const adapter = new PrismaPg(pool);
    const prisma = new PrismaClient({ adapter });

    const users = await prisma.user.findMany();

    ctx.waitUntil(pool.end());
    return Response.json({ users });
  }
};

重要:Prisma を Hyperdrive で動作させるには、ドライバーアダプター(@prisma/adapter-pg)が必要です。


ローカル開発

オプション 1:環境変数(推奨)

CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_<BINDING> 環境変数を設定します。

# If your binding is named "HYPERDRIVE"
export CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgres://user:password@localhost:5432/local_db"

# Start local dev server
npx wrangler dev

メリット:

  • wrangler.jsonc に認証情報を記載せずに済みます
  • 設定ファイルを安全にコミットできます
  • 開発者ごとに異なるローカルデータベースを使用できます

オプション 2:wrangler.jsonc の localConnectionString
{
  "hyperdrive": [
    {
      "binding": "HYPERDRIVE",
      "id": "production-hyperdrive-id",
      "localConnectionString": "postgres://user:password@localhost:5432/local_db"
    }
  ]
}

注意:実際の認証情報をバージョン管理にコミットしないでください。


オプション 3:リモート開発

ローカル開発中に本番データベースに接続します。

npx wrangler dev --remote

警告:本番データベースを使用します。変更を元に戻すことはできません。


クエリキャッシュ

キャッシュされるもの

Hyperdrive は、変更を伴わないクエリ(読み取り専用)を自動的にキャッシュします。

-- ✅ Cached
SELECT * FROM articles WHERE published = true ORDER BY date DESC LIMIT 50;
SELECT COUNT(*) FROM users;
SELECT * FROM products WHERE category = 'electronics';

-- ❌ NOT Cached
INSERT INTO users (name, email) VALUES ('John', '[email protected]');
UPDATE posts SET published = true WHERE id = 123;
DELETE FROM sessions WHERE expired = true;
SELECT LASTVAL();  -- PostgreSQL volatile function
SELECT LAST_INSERT_ID();  -- MySQL volatile function
仕組み
  1. ワイヤープロトコルの解析:Hyperdrive がデータベースプロトコルを解析し、変更操作を判別します
  2. 自動検出:設定は不要です
  3. エッジキャッシュ:Cloudflare のエッジ(ユーザーの近く)にキャッシュされます
  4. キャッシュの無効化:書き込みによって、関連するキャッシュ済みクエリが無効化されます
キャッシュの最適化

postgres.js - プリペアドステートメントを有効にする:

const sql = postgres(env.HYPERDRIVE.connectionString, {
  prepare: true  // CRITICAL for caching
});

prepare: true を指定しない場合、クエリはキャッシュできません。

キャッシュの状態

クエリがキャッシュされたかどうかを確認します。

const response = await fetch('https://your-worker.dev/api/users');
const cacheStatus = response.headers.get('cf-cache-status');
// Values: HIT, MISS, BYPASS, EXPIRED

TLS/SSL の設定

SSL モード

Hyperdrive は 3 つの TLS/SSL モードに対応しています。

  1. require(デフォルト)- TLS を必須とし、基本的な証明書検証を行います
  2. verify-ca - サーバー証明書が想定された CA によって署名されていることを検証します
  3. verify-full - CA を検証し、ホスト名が証明書の SAN と一致することを確認します
サーバー証明書(verify-ca / verify-full)

1. CA 証明書をアップロードします。

npx wrangler cert upload certificate-authority \
  --ca-cert root-ca.pem \
  --name my-ca-cert

2. CA を指定して Hyperdrive を作成します。

npx wrangler hyperdrive create my-db \
  --connection-string="postgres://..." \
  --ca-certificate-id <CA_CERT_ID> \
  --sslmode verify-full
クライアント証明書(mTLS)

クライアント認証が必要なデータベースの場合:

1. クライアント証明書とキーをアップロードします。

npx wrangler cert upload mtls-certificate \
  --cert client-cert.pem \
  --key client-key.pem \
  --name my-client-cert

2. クライアント証明書を指定して Hyperdrive を作成します。

npx wrangler hyperdrive create my-db \
  --connection-string="postgres://..." \
  --mtls-certificate-id <CERT_PAIR_ID>

プライベートデータベースへのアクセス(Cloudflare Tunnel)

プライベートネットワーク(VPC、オンプレミス)のデータベースに Hyperdrive を接続します。

1. cloudflared をインストールします。

# macOS
brew install cloudflare/cloudflare/cloudflared

# Linux
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64

2. トンネルを作成します。

cloudflared tunnel create my-db-tunnel

3. トンネルを設定します(config.yml)。

tunnel: <TUNNEL_ID>
credentials-file: /path/to/credentials.json

ingress:
  - hostname: db.example.com
    service: tcp://localhost:5432  # Your private database
  - service: http_status:404

4. トンネルを実行します。

cloudflared tunnel run my-db-tunnel

5. Hyperdrive を作成します。

npx wrangler hyperdrive create my-private-db \
  --connection-string="postgres://user:[email protected]:5432/database"

重要なルール

必ず行うこと

✅ compatibility_flags に nodejs_compat を含める
✅ 接続のクリーンアップに ctx.waitUntil(client.end()) を使用する
✅ コネクションプールの max: 5 を設定する(Workers の上限:6)
✅ データベースで TLS/SSL を有効にする(Hyperdrive で必須です)
✅ キャッシュにはプリペアドステートメントを使用する(postgres.js:prepare: true)
✅ mysql2 ドライバーでは disableEval: true を設定する
✅ try/catch でエラーを適切に処理する
✅ ローカル開発用の接続文字列には環境変数を使用する
✅ デプロイ前に wrangler dev でローカルテストを行う

決して行わないこと

❌ nodejs_compat フラグを省略する(「No such module」エラーの原因になります) ❌ プライベート IP アドレスを直接使用する(代わりに Cloudflare Tunnel を使用してください) ❌ await client.end() を使用する(レスポンスがブロックされます。代わりに ctx.waitUntil() を使用してください) ❌ 接続プールの max を 5 より大きく設定する(Workers の接続上限 6 を超えます) ❌ すべてのクエリをトランザクションで囲む(接続の多重化が制限されます) ❌ SQL レベルの PREPARE/EXECUTE/DEALLOCATE を使用する(サポートされていません) ❌ アドバイザリロックや LISTEN/NOTIFY を使用する(PostgreSQL でサポートされていない機能です) ❌ MySQL で複数ステートメントのクエリを使用する(サポートされていません) ❌ データベースの認証情報をバージョン管理にコミットする


Wrangler コマンドのリファレンス

# Create Hyperdrive configuration
wrangler hyperdrive create <name> --connection-string="postgres://..."

# List all Hyperdrive configurations
wrangler hyperdrive list

# Get details of a configuration
wrangler hyperdrive get <hyperdrive-id>

# Update connection string
wrangler hyperdrive update <hyperdrive-id> --connection-string="postgres://..."

# Delete configuration
wrangler hyperdrive delete <hyperdrive-id>

# Upload CA certificate
wrangler cert upload certificate-authority --ca-cert <file>.pem --name <name>

# Upload client certificate pair
wrangler cert upload mtls-certificate --cert <cert>.pem --key <key>.pem --name <name>

サポート対象のデータベース

PostgreSQL(v9.0 - 17.x)
  • ✅ AWS RDS / Aurora
  • ✅ Google Cloud SQL
  • ✅ Azure Database for PostgreSQL
  • ✅ Neon
  • ✅ Supabase
  • ✅ PlanetScale(PostgreSQL)
  • ✅ Timescale
  • ✅ CockroachDB
  • ✅ Materialize
  • ✅ Fly.io
  • ✅ pgEdge Cloud
  • ✅ Prisma Postgres
MySQL(v5.7 - 8.x)
  • ✅ AWS RDS / Aurora
  • ✅ Google Cloud SQL
  • ✅ Azure Database for MySQL
  • ✅ PlanetScale(MySQL)
サポート対象外
  • ❌ SQL Server
  • ❌ MongoDB(NoSQL)
  • ❌ Oracle Database

サポート対象外の機能

PostgreSQL
  • SQL レベルのプリペアドステートメント(PREPARE、EXECUTE、DEALLOCATE)
  • アドバイザリロック
  • LISTEN と NOTIFY
  • セッションごとの状態変更
MySQL
  • クエリ内の非 UTF-8 文字
  • USE ステートメント
  • 複数ステートメントのクエリ
  • プロトコルレベルのプリペアドステートメント(COM_STMT_PREPARE)
  • COM_INIT_DB メッセージ
  • caching_sha2_password または mysql_native_password 以外の認証プラグイン

回避策:サポート対象外の機能については、2 つ目の直接接続クライアント(Hyperdrive を使用しないもの)を作成してください。


パフォーマンスに関するベストプラクティス

  1. 長時間実行されるトランザクションを避ける - 接続の多重化が制限されます
  2. プリペアドステートメントを使用する - クエリキャッシュが有効になります(postgres.js:prepare: true)
  3. プールの max を 5 に設定する - Workers の接続上限 6 以内に収まります
  4. 不要であれば fetch_types を無効にする - レイテンシが低減します(postgres.js)
  5. クリーンアップには ctx.waitUntil() を使用する - 接続のクローズがブロックされません
  6. キャッシュに適したクエリを使用する - 複雑な結合より SELECT を優先します
  7. 頻繁にクエリされるカラムにインデックスを設定する - クエリのパフォーマンスが向上します
  8. Hyperdrive の分析機能で監視する - キャッシュヒット率とレイテンシを追跡します

トラブルシューティング

解決策を含むエラーの完全なリファレンスについては、references/troubleshooting.md を参照してください。

簡単な解決方法:

エラー解決策
"No such module 'node:*'"compatibility_flags に nodejs_compat を追加します
"TLS not supported by database"データベースで SSL/TLS を有効にします
"Connection refused"ファイアウォールルールを確認し、パブリックインターネットを許可するか Tunnel を使用します
"Failed to acquire connection"クリーンアップに ctx.waitUntil() を使用し、長時間のトランザクションを避けます
"Code generation from strings disallowed"mysql2 の設定で disableEval: true を設定します
"Bad hostname"DNS が名前解決できることを確認し、入力ミスがないか確認します
"Invalid database credentials"ユーザー名/パスワードを確認します(大文字と小文字は区別されます)

メトリクスと分析

ダッシュボードで Hyperdrive のメトリクスを確認できます。

  1. Hyperdrive ダッシュボードに移動します
  2. 設定を選択します
  3. Metrics タブをクリックします

利用可能なメトリクス:

  • クエリ数
  • キャッシュヒット率(ヒット対ミス)
  • クエリレイテンシ(p50、p95、p99)
  • 接続レイテンシ
  • クエリのバイト数/結果のバイト数
  • エラー率

移行方法

データベースへの直接接続からの移行

変更前(直接接続):

const client = new Client({
  host: 'db.example.com',
  user: 'myuser',
  password: 'mypassword',
  database: 'mydb',
  port: 5432
});

変更後(Hyperdrive を使用):

const client = new Client({
  connectionString: env.HYPERDRIVE.connectionString
});

メリット:

  • ✅ 7 回のラウンドトリップを削減
  • ✅ クエリキャッシュが有効
  • ✅ 接続プーリングを自動化
  • ✅ グローバルなパフォーマンスが向上

D1 から Hyperdrive への移行

移行するタイミング:

  • PostgreSQL/MySQL の機能(JSON 型、全文検索など)が必要な場合
  • 既存のデータベースにデータがある場合
  • マルチリージョンの読み取りレプリカが必要な場合
  • 高度なインデックス戦略が必要な場合

D1 を使い続ける場合:

  • Cloudflare ネイティブのアプリを新しく構築する場合
  • SQLite の機能で十分な場合
  • 移行する既存のデータベースがない場合
  • よりシンプルなサーバーレス環境を構築したい場合

認証情報のローテーション

オプション 1:新しい Hyperdrive 構成を作成する

# Create new config with new credentials
wrangler hyperdrive create my-db-v2 --connection-string="postgres://..."

# Update wrangler.jsonc to use new ID
# Deploy gradually (no downtime)
# Delete old config when migration complete

オプション 2:既存の構成を更新する

wrangler hyperdrive update <id> --connection-string="postgres://new-credentials@..."

ベストプラクティス:ステージング環境と本番環境には、それぞれ別の Hyperdrive 構成を使用してください。


例

動作する完全な例については、templates/ ディレクトリを参照してください。

  • postgres-basic.ts - pg.Client を使ったシンプルなクエリ
  • postgres-pool.ts - pg.Pool を使った並列クエリ
  • postgres-js.ts - postgres.js ドライバーの使用
  • mysql2-basic.ts - mysql2 ドライバーを使った MySQL
  • drizzle-postgres.ts - Drizzle ORM との統合
  • drizzle-mysql.ts - MySQL での Drizzle ORM の使用
  • prisma-postgres.ts - Prisma ORM との統合

参考資料


最終更新日:2025-10-22 パッケージバージョン:[email protected]+、[email protected]+、[email protected]+、[email protected]+ 本番環境でのテスト済み:Cloudflare の公式ドキュメントおよびコミュニティの例に基づいています

コメント