🎯

cloudflare-hyperdrive

🎯Skill

from ovachiever/droid-tings

VibeIndex|
What it does

Connects Cloudflare Workers to PostgreSQL/MySQL databases with global connection pooling and caching, reducing latency and simplifying database integrations.

πŸ“¦

Part of

ovachiever/droid-tings(370 items)

cloudflare-hyperdrive

Installation

npxRun with npx
npx wrangler hyperdrive create my-postgres-db \
npxRun with npx
npx wrangler hyperdrive create my-mysql-db \
npxRun with npx
npx wrangler deploy
npxRun with npx
npx wrangler dev
npxRun with npx
npx wrangler dev --remote # ⚠️ Uses PRODUCTION database

+ 4 more commands

πŸ“– Extracted from docs: ovachiever/droid-tings
15Installs
20
-
AddedFeb 4, 2026

Skill Details

SKILL.md

|

Overview

# Cloudflare Hyperdrive

Status: Production Ready βœ…

Last Updated: 2025-11-23

Dependencies: cloudflare-worker-base (recommended for Worker setup)

Latest Versions: wrangler@4.50.0, pg@8.16.3+ (minimum), postgres@3.4.7, mysql2@3.15.3

Recent Updates (2025):

  • July 2025: Configurable connection counts (min 5, max ~20 Free/~100 Paid)
  • May 2025: 5x faster cache hits (regional prepared statement caching), FedRAMP Moderate authorization
  • April 2025: Free plan availability (10 configs), MySQL GA support
  • March 2025: 90% latency reduction (pools near database), IP access control (standard CF IP ranges)
  • nodejs_compat_v2: pg driver no longer requires node_compat mode (auto-enabled with compatibility_date 2024-09-23+)
  • Limits: 25 Hyperdrive configurations per account (Paid), 10 per account (Free)

---

Quick Start (5 Minutes)

1. Create Hyperdrive Configuration

```bash

# For PostgreSQL

npx wrangler hyperdrive create my-postgres-db \

--connection-string="postgres://user:password@db-host.cloud:5432/database"

# For MySQL

npx wrangler hyperdrive create my-mysql-db \

--connection-string="mysql://user:password@db-host.cloud:3306/database"

# Output:

# βœ… Successfully created Hyperdrive configuration

#

# [[hyperdrive]]

# binding = "HYPERDRIVE"

# id = "a76a99bc-7901-48c9-9c15-c4b11b559606"

```

Save the id value - you'll need it in the next step!

---

2. Configure Bindings in wrangler.jsonc

Add to your wrangler.jsonc:

```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

}

]

}

```

CRITICAL:

  • nodejs_compat flag is REQUIRED for all database drivers
  • binding is how you access Hyperdrive in code (env.HYPERDRIVE)
  • id is the Hyperdrive configuration ID (NOT your database ID)

---

3. Install Database Driver

```bash

# 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. Query Your Database

PostgreSQL with node-postgres (pg):

```typescript

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());

}

}

};

```

MySQL with mysql2:

```typescript

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. Deploy

```bash

npx wrangler deploy

```

That's it! Your Worker now connects to your existing database via Hyperdrive with:

  • βœ… Global connection pooling
  • βœ… Automatic query caching
  • βœ… Reduced latency (eliminates 7 round trips)

---

How Hyperdrive Works

Hyperdrive eliminates 7 connection round trips (TCP + TLS + auth) by:

  • Edge connection setup near Worker (low latency)
  • Connection pooling near database (March 2025: 90% latency reduction)
  • Query caching at edge (May 2025: 5x faster cache hits)

Result: Single-region databases feel globally distributed.

---

Setup Steps

Prerequisites

  • Cloudflare account with Workers access
  • PostgreSQL (v9.0-17.x) or MySQL (v5.7-8.x) database
  • Database accessible via public internet (TLS/SSL required) or private network (Cloudflare Tunnel)
  • April 2025: Available on Free plan (10 configs) and Paid plan (25 configs)

Connection String Formats

```bash

# PostgreSQL

postgres://user:password@host:5432/database

postgres://user:password@host:5432/database?sslmode=require

# MySQL

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

# URL-encode special chars: p@ssw$rd β†’ p%40ssw%24rd

```

---

Connection Patterns

Single Connection (pg.Client)

```typescript

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

await client.connect();

const result = await client.query('SELECT ...');

ctx.waitUntil(client.end()); // CRITICAL: Non-blocking cleanup

```

Use for: Simple queries, single query per request

Connection Pool (pg.Pool)

```typescript

const pool = new Pool({

connectionString: env.HYPERDRIVE.connectionString,

max: 5 // CRITICAL: Workers limit is 6 connections (July 2025: configurable ~20 Free, ~100 Paid)

});

const [result1, result2] = await Promise.all([

pool.query('SELECT ...'),

pool.query('SELECT ...')

]);

ctx.waitUntil(pool.end());

```

Use for: Parallel queries in single request

Connection Cleanup Rule

ALWAYS use ctx.waitUntil(client.end()) - non-blocking cleanup after response sent

NEVER use await client.end() - blocks response, adds latency

---

ORM Integration

Drizzle ORM

```typescript

import { drizzle } from "drizzle-orm/postgres-js";

import postgres from "postgres";

const sql = postgres(env.HYPERDRIVE.connectionString, { max: 5 });

const db = drizzle(sql);

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

ctx.waitUntil(sql.end());

```

Prisma ORM

```typescript

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

import { PrismaClient } from "@prisma/client";

import { Pool } from "pg";

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());

```

Note: Prisma requires driver adapters (@prisma/adapter-pg).

---

Local Development

Option 1: Environment Variable (Recommended)

```bash

export CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgres://user:password@localhost:5432/local_db"

npx wrangler dev

```

Safe to commit config, no credentials in wrangler.jsonc.

Option 2: localConnectionString in wrangler.jsonc

```jsonc

{ "hyperdrive": [{ "binding": "HYPERDRIVE", "id": "prod-id", "localConnectionString": "postgres://..." }] }

```

⚠️ Don't commit credentials to version control.

Option 3: Remote Development

```bash

npx wrangler dev --remote # ⚠️ Uses PRODUCTION database

```

---

Query Caching

Cached: SELECT (non-mutating queries)

NOT Cached: INSERT, UPDATE, DELETE, volatile functions (LASTVAL, LAST_INSERT_ID)

May 2025: 5x faster cache hits via regional prepared statement caching.

Critical for postgres.js:

```typescript

const sql = postgres(env.HYPERDRIVE.connectionString, {

prepare: true // REQUIRED for caching

});

```

Check cache status:

```typescript

response.headers.get('cf-cache-status'); // HIT, MISS, BYPASS, EXPIRED

```

---

TLS/SSL Configuration

SSL Modes: require (default), verify-ca (verify CA), verify-full (verify CA + hostname)

Server Certificates (verify-ca/verify-full):

```bash

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

npx wrangler hyperdrive create my-db --connection-string="postgres://..." --ca-certificate-id --sslmode verify-full

```

Client Certificates (mTLS):

```bash

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

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

```

---

Private Database Access (Cloudflare Tunnel)

Connect to databases in private networks (VPCs, on-premises):

```bash

# 1. Install cloudflared (macOS: brew install cloudflare/cloudflare/cloudflared)

# 2. Create tunnel

cloudflared tunnel create my-db-tunnel

# 3. Configure config.yml

# tunnel:

# ingress:

# - hostname: db.example.com

# service: tcp://localhost:5432

# 4. Run tunnel

cloudflared tunnel run my-db-tunnel

# 5. Create Hyperdrive

npx wrangler hyperdrive create my-private-db --connection-string="postgres://user:password@db.example.com:5432/database"

```

---

Critical Rules

Always Do

βœ… Include nodejs_compat in compatibility_flags

βœ… Use ctx.waitUntil(client.end()) for connection cleanup

βœ… Set max: 5 for connection pools (Workers limit: 6)

βœ… Enable TLS/SSL on your database (Hyperdrive requires it)

βœ… Use prepared statements for caching (postgres.js: prepare: true)

βœ… Set disableEval: true for mysql2 driver

βœ… Handle errors gracefully with try/catch

βœ… Use environment variables for local development connection strings

βœ… Test locally with wrangler dev before deploying

Never Do

❌ Skip nodejs_compat flag (causes "No such module" errors)

❌ Use private IP addresses directly (use Cloudflare Tunnel instead)

❌ Use await client.end() (blocks response, use ctx.waitUntil())

❌ Set connection pool max > 5 (exceeds Workers' 6 connection limit)

❌ Wrap all queries in transactions (limits connection multiplexing)

❌ Use SQL-level PREPARE/EXECUTE/DEALLOCATE (unsupported)

❌ Use advisory locks, LISTEN/NOTIFY (PostgreSQL unsupported features)

❌ Use multi-statement queries in MySQL (unsupported)

❌ Commit database credentials to version control

---

Wrangler Commands Reference

```bash

# Create Hyperdrive configuration

wrangler hyperdrive create --connection-string="postgres://..."

# List all Hyperdrive configurations

wrangler hyperdrive list

# Get details of a configuration

wrangler hyperdrive get

# Update connection string

wrangler hyperdrive update --connection-string="postgres://..."

# Delete configuration

wrangler hyperdrive delete

# Upload CA certificate

wrangler cert upload certificate-authority --ca-cert .pem --name

# Upload client certificate pair

wrangler cert upload mtls-certificate --cert .pem --key .pem --name

```

---

Supported Databases

PostgreSQL (v9.0-17.x): AWS RDS/Aurora, Google Cloud SQL, Azure, Neon, Supabase, PlanetScale, Timescale, CockroachDB, Materialize, Fly.io, pgEdge, Prisma Postgres

MySQL (v5.7-8.x): AWS RDS/Aurora, Google Cloud SQL, Azure, PlanetScale, MariaDB (April 2025 GA)

NOT Supported: SQL Server, MongoDB, Oracle

---

Unsupported Features

PostgreSQL

  • SQL-level prepared statements (PREPARE, EXECUTE, DEALLOCATE)
  • Advisory locks
  • LISTEN and NOTIFY
  • Per-session state modifications

MySQL

  • Non-UTF8 characters in queries
  • USE statements
  • Multi-statement queries
  • Protocol-level prepared statements (COM_STMT_PREPARE)
  • COM_INIT_DB messages
  • Auth plugins other than caching_sha2_password or mysql_native_password

Workaround: For unsupported features, create a second direct client connection (without Hyperdrive).

---

Performance Best Practices

  1. Avoid long-running transactions - Limits connection multiplexing
  2. Use prepared statements - Enables query caching (postgres.js: prepare: true)
  3. Set max: 5 for pools - Stays within Workers' 6 connection limit
  4. Disable fetch_types if not needed - Reduces latency (postgres.js)
  5. Use ctx.waitUntil() for cleanup - Non-blocking connection close
  6. Cache-friendly queries - Prefer SELECT over complex joins
  7. Index frequently queried columns - Improves query performance
  8. Monitor with Hyperdrive analytics - Track cache hit ratios and latency

---

Troubleshooting

See references/troubleshooting.md for complete error reference with solutions.

Quick fixes:

| Error | Solution |

|-------|----------|

| "No such module 'node:*'" | Add nodejs_compat to compatibility_flags |

| "TLS not supported by database" | Enable SSL/TLS on your database |

| "Connection refused" | Check firewall rules, allow public internet or use Tunnel |

| "Failed to acquire connection" | Use ctx.waitUntil() for cleanup, avoid long transactions |

| "Code generation from strings disallowed" | Set disableEval: true in mysql2 config |

| "Bad hostname" | Verify DNS resolves, check for typos |

| "Invalid database credentials" | Check username/password (case-sensitive) |

---

Metrics and Analytics

[Hyperdrive Dashboard](https://dash.cloudflare.com/?to=/:account/workers/hyperdrive) β†’ Select config β†’ Metrics tab

Available: Query count, cache hit ratio, query latency (p50/p95/p99), connection latency, query/result bytes, error rate

---

Credential Rotation

```bash

# Option 1: Create new config (zero downtime)

wrangler hyperdrive create my-db-v2 --connection-string="postgres://new-creds..."

# Update wrangler.jsonc, deploy, delete old config

# Option 2: Update existing

wrangler hyperdrive update --connection-string="postgres://new-creds..."

```

Best practice: Separate configs for staging/production.

---

References

  • [Official Documentation](https://developers.cloudflare.com/hyperdrive/)
  • [Get Started Guide](https://developers.cloudflare.com/hyperdrive/get-started/)
  • [How Hyperdrive Works](https://developers.cloudflare.com/hyperdrive/configuration/how-hyperdrive-works/)
  • [Query Caching](https://developers.cloudflare.com/hyperdrive/configuration/query-caching/)
  • [Local Development](https://developers.cloudflare.com/hyperdrive/configuration/local-development/)
  • [TLS/SSL Certificates](https://developers.cloudflare.com/hyperdrive/configuration/tls-ssl-certificates-for-hyperdrive/)
  • [Troubleshooting Guide](https://developers.cloudflare.com/hyperdrive/observability/troubleshooting/)
  • [Wrangler Commands](https://developers.cloudflare.com/hyperdrive/reference/wrangler-commands/)
  • [Supported Databases](https://developers.cloudflare.com/hyperdrive/reference/supported-databases-and-features/)

---

Last Updated: 2025-11-23

Package Versions: wrangler@4.50.0, pg@8.16.3+ (minimum), postgres@3.4.7, mysql2@3.15.3

Production Tested: Based on official Cloudflare documentation and community examples