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
bashbunx wrangler hyperdrive create my-db \ --connection-string="postgres://user:pass@host:5432/database"
Save the id!
2. Configure Binding
jsonc{ "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
bashbun add pg # or postgres, or mysql2
4. Query Database
typescriptimport { 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)
typescriptimport { 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)
typescriptimport postgres from 'postgres'; const sql = postgres(env.HYPERDRIVE.connectionString); const users = await sql`SELECT * FROM users`;
MySQL
typescriptimport 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
typescriptimport { 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
typescriptexport 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
typescriptconst 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
typescriptconst 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
PostgreSQL:
- Amazon RDS
- Amazon Aurora
- Neon
- Supabase
- Railway
- Render
- DigitalOcean
- Any PostgreSQL 11+
MySQL:
- Amazon RDS
- Amazon Aurora
- PlanetScale
- Any MySQL 5.7+
Official Documentation
- Hyperdrive Overview: https://developers.cloudflare.com/hyperdrive/
- Get Started: https://developers.cloudflare.com/hyperdrive/get-started/
- Configuration: https://developers.cloudflare.com/hyperdrive/configuration/
Bundled Resources
References (references/):
setup-guide.md- Complete setup walkthrough (create config, bind, query)connection-pooling.md- Connection pool configuration and best practicesquery-caching.md- Query caching strategies and optimizationdrizzle-integration.md- Drizzle ORM integration patternsprisma-integration.md- Prisma ORM integration patternssupported-databases.md- Complete list of supported PostgreSQL and MySQL providerstls-ssl-setup.md- TLS/SSL configuration for secure connectionstroubleshooting.md- Common issues and solutionswrangler-commands.md- Complete wrangler CLI commands for Hyperdrive
Templates (templates/):
postgres-basic.ts- Basic PostgreSQL with node-postgrespostgres-js.ts- PostgreSQL with postgres.js driverpostgres-pool.ts- PostgreSQL with connection poolingmysql2-basic.ts- MySQL with mysql2 driverdrizzle-postgres.ts- Drizzle ORM with PostgreSQLdrizzle-mysql.ts- Drizzle ORM with MySQLprisma-postgres.ts- Prisma ORM with PostgreSQLlocal-dev-setup.sh- Local development setup scriptwrangler-hyperdrive-config.jsonc- Wrangler configuration example
Questions? Issues?
- Check
references/setup-guide.mdfor complete setup - Verify nodejs_compat flag enabled
- Ensure using env.HYPERDRIVE.connectionString
- Check connection properly closed

