Workers Hyperdrive -- Accelerate Database Connections
In this tutorial, you'll learn about Workers Hyperdrive. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Cloudflare Workers Hyperdrive is a connection pooling and acceleration service that dramatically reduces database connection latency from Workers by maintaining persistent, warm connections to your database across Cloudflare's global edge network.
Why Hyperdrive Matters
Every time a Worker connects to a traditional database, it must establish a new TCP connection, perform a TLS handshake, and often authenticate. These steps add 100-500 milliseconds of overhead before a single query runs. Worse, databases have connection limits -- each new connection consumes server resources. Hyperdrive solves both problems by maintaining a pool of persistent, warm TCP connections from edge locations to your database. When a Worker issues a query, Hyperdrive routes it through an already-established connection, eliminating connection setup overhead. This is especially impactful for Workers using Cloudflare's Serverless platform, which are stateless and cannot reuse connections across invocations. Hyperdrive works with PostgreSQL-compatible databases and MySQL. Unlike REST APIs which abstract database calls behind HTTP, Hyperdrive supports native database protocols for full SQL capability.
Real-world use: A Worker processes 200 requests per second, each requiring a PostgreSQL query. Without Hyperdrive, each request spends 150ms connecting and 20ms querying. With Hyperdrive, connection time drops to under 5ms, reducing total latency by 85% and database server load by eliminating connection storms.
Hyperdrive Architecture
flowchart TD
W1[Worker Request 1] --> H[Hyperdrive]
W2[Worker Request 2] --> H
W3[Worker Request 3] --> H
H --> CP[Connection Pool]
CP --> C1[Warm Connection 1]
CP --> C2[Warm Connection 2]
CP --> C3[Warm Connection N]
C1 --> DB[(PostgreSQL/MySQL)]
C2 --> DB
C3 --> DB
subgraph Without_Hyperdrive
W4[Worker] --> N1[New TCP + TLS]
N1 --> DB2[(Database)]
end
style H fill:#f90,color:#fff
style CP fill:#3498db,color:#fff
style DB fill:#2ecc71,color:#fff
style N1 fill:#e74c3c,color:#fff
Hyperdrive maintains a configurable pool of connections from Cloudflare's edge to your database. The pool size, idle timeout, and maximum age are configurable. Connections are established from Cloudflare's IP range, so you can firewall your database to accept only Cloudflare traffic.
Setting Up Hyperdrive
# Step 1: Create a Hyperdrive configuration
npx wrangler hyperdrive create my-db-config \
--database="postgresql://user:password@db.example.com:5432/mydb" \
--pool-size=10 \
--max-age=60
# Expected output:
# ✔ Created Hyperdrive configuration "my-db-config"
# ID: abc12345-6789-def0-1234-56789abcdef0
# Connection string: postgresql://user:password@db.example.com:5432/mydb
# Pool size: 10
# Max age: 60 seconds
# Step 2: Bind Hyperdrive to your Worker in wrangler.toml
# wrangler.toml
name = "hyperdrive-worker"
main = "src/index.js"
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "abc12345-6789-def0-1234-56789abcdef0"
Hyperdrive configurations are created with the Wrangler CLI. The configuration stores the database connection string securely and defines pool behavior. Multiple Workers can share the same Hyperdrive configuration.
Querying PostgreSQL through Hyperdrive
export default {
async fetch(request, env) {
// env.HYPERDRIVE contains the connection string
const connectionString = env.HYPERDRIVE.connectionString;
// Use your preferred PostgreSQL driver
// For neon: npm install @neondatabase/serverless
// For pg: npm install pg (with connection pooling)
const { Pool } = await import('@neondatabase/serverless');
const pool = new Pool({ connectionString });
try {
const result = await pool.query(
'SELECT id, name, email, created_at FROM users ORDER BY created_at DESC LIMIT 10'
);
return new Response(JSON.stringify(result.rows), {
headers: { 'Content-Type': 'application/json' }
});
} finally {
// Don't close the pool -- Hyperdrive manages connections
// Just release the client back to the pool
}
}
};
// Expected output (response time comparison):
// Without Hyperdrive: ~180ms (150ms connect + 30ms query)
// With Hyperdrive: ~35ms (5ms pool reuse + 30ms query)
//
// Actual data returned:
// [{"id":1,"name":"Alice","email":"alice"@example".com","created_at":"2026-06-01T00:00:00.000Z"},...]
The connection string from env.HYPERDRIVE.connectionString points to Hyperdrive's proxy rather than directly to your database. Hyperdrive handles connection pooling transparently. Your existing PostgreSQL driver code works without modification.
Using Hyperdrive with D1 for Hybrid Storage
export default {
async fetch(request, env) {
const url = new URL(request.url);
const { Pool } = await import('@neondatabase/serverless');
const pool = new Pool({ connectionString: env.HYPERDRIVE.connectionString });
if (url.pathname.startsWith('/api/users')) {
// PostgreSQL via Hyperdrive for complex queries
const result = await pool.query(`
SELECT u.*, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.active = true
GROUP BY u.id
HAVING COUNT(o.id) > 5
ORDER BY order_count DESC
`);
return new Response(JSON.stringify(result.rows), {
headers: { 'Content-Type': 'application/json' }
});
}
if (url.pathname.startsWith('/api/cache')) {
// D1 for simple key-value lookups
const { results } = await env.DB.prepare(
'SELECT value FROM cache WHERE key = ?'
).bind(url.searchParams.get('key')).first();
return new Response(results?.value || 'Not found');
}
return new Response('Not found', { status: 404 });
}
};
// Expected behavior:
// /api/users -> complex JOIN query via Hyperdrive/PostgreSQL (~40ms)
// /api/cache?key=config -> simple lookup via D1 (~5ms)
// Combines transactional PostgreSQL with edge-cached D1 for optimal performance
Hyperdrive excels for complex relational queries (JOINs, aggregations, transactions) that are impractical on key-value stores. Combine Hyperdrive with D1 for a hybrid architecture: D1 for simple cached lookups, Hyperdrive-connected PostgreSQL for complex queries.
Pool Size Configuration
// Adjust pool behavior based on traffic patterns
export default {
async fetch(request, env) {
// Hyperdrive is configured at the database level, not per-request
// But you can manage connection usage in your code
const { Pool } = await import('@neondatabase/serverless');
const pool = new Pool({
connectionString: env.HYPERDRIVE.connectionString,
max: 5, // Max connections per Worker instance
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 10000,
});
// Run parallel queries through the same pool
const [users, orders, products] = await Promise.all([
pool.query('SELECT COUNT(*) FROM users'),
pool.query('SELECT SUM(total) FROM orders WHERE status = $1', ['completed']),
pool.query('SELECT COUNT(*) FROM products WHERE stock = 0'),
]);
const metrics = {
users: users.rows[0].count,
revenue: orders.rows[0].sum,
outOfStock: products.rows[0].count
};
return new Response(JSON.stringify(metrics), {
headers: { 'Content-Type': 'application/json' }
});
}
};
// Expected output:
// {"users":15230,"revenue":1245000.50,"outOfStock":47}
// All three queries reuse the same pooled connection
Hyperdrive manages the global Connection Pool, but you still configure per-instance pool parameters through your database driver. The combination of Hyperdrive's global pooling and your driver's local pooling gives maximum throughput with minimal database connections.
Common Errors
| Error | Cause | Fix |
|---|---|---|
Connection refused |
Database firewall blocks Cloudflare IPs | Allow Cloudflare's IP range (available in Cloudflare docs) to access the database |
Too many connections |
Pool size exceeds database max_connections | Reduce Hyperdrive's --pool-size or increase your database's max_connections |
SSL required |
Database requires TLS but Hyperdrive not configured | Use sslmode=require in the connection string or set --ssl flag when creating Hyperdrive |
Connection string invalid |
Malformed database URL | Verify the format: <a href="/databases/postgresql/">PostgreSQL</a>://user:password@host:port/database |
Hyperdrive binding not found |
Missing or incorrect binding in wrangler.toml | Ensure [[hyperdrive]] has the correct binding name and id |
Practice Questions
- What is the primary latency bottleneck that Hyperdrive eliminates?
- How do you bind a Hyperdrive configuration to a Worker?
- What types of database queries benefit most from Hyperdrive acceleration?
FAQ
Summary
Workers Hyperdrive accelerates database connections from Workers by maintaining warm, pooled TCP connections across Cloudflare's edge network. Create a Hyperdrive configuration with Wrangler, bind it to your Worker, and use the provided connection string with your standard database driver. Connection setup time drops from hundreds of milliseconds to under 5 milliseconds. Hyperdrive supports PostgreSQL and MySQL databases and is ideal for Workers that perform complex relational queries. DodaTech uses Hyperdrive to power real-time dashboards that query customer data across millions of records without overwhelming the database.
This guide is brought to you by the developers of Cloudflare, PostgreSQL databases, and Durga Antivirus Pro at DodaTech.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro