Overview Install Files SecuritySummary Cloudflare Hyperdrive for Workers-to-database connections with pooling and caching. Use for PostgreSQL/MySQL, Drizzle/Prisma, or encountering pool errors, TLS issues, connection refused.
Cloudflare Hyperdrive
Status : Production Ready ✅ | Last Verified : 2025-11-18
What Is Hyperdrive?
Connect Workers to existing PostgreSQL/MySQL databases:
Global connection pooling
Query caching
Reduced latency
Works with node-postgres, postgres.js, mysql2
Quick Start (5 Minutes)
1. Create Hyperdrive Config
bunx wrangler hyperdrive create my-db \
--connection-string="postgres://user:pass@host:5432/database"
Save the id!
2. Configure Binding
{
"name": "my-worker",
"main": "src/index.ts",
"compatibility_date": "2024-09-23",
"compatibility_flags": ["nodejs_compat"], // REQUIRED!
"hyperdrive": [
{
"binding": "HYPERDRIVE",
"id": "<ID_FROM_STEP_1>"
}
]
}
3. Install Driver
bun add pg # or postgres, or mysql2
4. Query Database
import { Client } from 'pg';
export default {
async fetch(request, env, ctx) {
const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
await client.connect();
const result = await client.query('SELECT * FROM users LIMIT 10');
await client.end();
return Response.json(result.rows);
}
};
Load references/setup-guide.md for complete walkthrough.
Critical Rules
Always Do ✅
Enable nodejs_compat flag (required!)
Use env.HYPERDRIVE.connectionString (not original DB string)
Close connections after queries
Handle errors explicitly
Use connection pooling (built-in)
Test locally with wrangler dev
Monitor query performance
Use prepared statements
Enable query caching (automatic)
Secure connection strings (use secrets)
Never Do ❌
Never skip nodejs_compat (drivers won't work)
Never use original DB connection string in Workers
Never leave connections open (pool exhaustion)
Never skip error handling (DB can fail)
Never hardcode credentials in code
Never exceed connection limits
Never use eval/Function (blocked in Workers)
Never skip TLS for production DBs
Never use blocking queries (Worker timeout)
Never expose DB errors to users
Database Drivers
PostgreSQL (node-postgres) import { Client } from 'pg';
const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
await client.connect();
const result = await client.query('SELECT * FROM users');
await client.end();
PostgreSQL (postgres.js) import postgres from 'postgres';
const sql = postgres(env.HYPERDRIVE.connectionString);
const users = await sql`SELECT * FROM users`;
MySQL import mysql from 'mysql2/promise';
const connection = await mysql.createConnection(env.HYPERDRIVE.connectionString);
const [rows] = await connection.execute('SELECT * FROM users');
await connection.end();
With Drizzle ORM import { drizzle } from 'drizzle-orm/node-postgres';
import { Client } from 'pg';
const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
await client.connect();
const db = drizzle(client);
const users = await db.select().from(usersTable);
await client.end();
Common Use Cases
Use Case 1: Read-Only Queries export default {
async fetch(request, env, ctx) {
const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
await client.connect();
const users = await client.query('SELECT * FROM users WHERE active = true');
await client.end();
return Response.json(users.rows);
}
};
Use Case 2: Parameterized Queries const userId = new URL(request.url).searchParams.get('id');
const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
await client.connect();
const result = await client.query(
'SELECT * FROM users WHERE id = $1',
[userId]
);
await client.end();
Use Case 3: Transactions const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
await client.connect();
try {
await client.query('BEGIN');
await client.query('UPDATE accounts SET balance = balance - 100 WHERE id = $1', [1]);
await client.query('UPDATE accounts SET balance = balance + 100 WHERE id = $1', [2]);
await client.query('COMMIT');
} catch (e) {
await client.query('ROLLBACK');
throw e;
} finally {
await client.end();
}
Supported Databases
Amazon RDS
Amazon Aurora
Neon
Supabase
Railway
Render
DigitalOcean
Any PostgreSQL 11+
Amazon RDS
Amazon Aurora
PlanetScale
Any MySQL 5.7+
Official Documentation
Bundled Resources References (references/):
setup-guide.md - Complete setup walkthrough (create config, bind, query)
connection-pooling.md - Connection pool configuration and best practices
query-caching.md - Query caching strategies and optimization
drizzle-integration.md - Drizzle ORM integration patterns
prisma-integration.md - Prisma ORM integration patterns
supported-databases.md - Complete list of supported PostgreSQL and MySQL providers
tls-ssl-setup.md - TLS/SSL configuration for secure connections
troubleshooting.md - Common issues and solutions
wrangler-commands.md - Complete wrangler CLI commands for Hyperdrive
postgres-basic.ts - Basic PostgreSQL with node-postgres
postgres-js.ts - PostgreSQL with postgres.js driver
postgres-pool.ts - PostgreSQL with connection pooling
mysql2-basic.ts - MySQL with mysql2 driver
drizzle-postgres.ts - Drizzle ORM with PostgreSQL
drizzle-mysql.ts - Drizzle ORM with MySQL
prisma-postgres.ts - Prisma ORM with PostgreSQL
local-dev-setup.sh - Local development setup script
wrangler-hyperdrive-config.jsonc - Wrangler configuration example
Check references/setup-guide.md for complete setup
Verify nodejs_compat flag enabled
Ensure using env.HYPERDRIVE.connectionString
Check connection properly closed