PostgreSQL
Void supports PostgreSQL via Cloudflare Hyperdrive. You bring the Postgres database, and Void handles connection pooling plus deployment wiring through the same Drizzle-based workflow used for D1.
What is Hyperdrive?
Hyperdrive is Cloudflare's connection pooling and caching layer for PostgreSQL. It maintains persistent connections from the edge to your database, dramatically reducing connection latency. Instead of establishing a new TCP + TLS connection on every request, your Worker reuses pooled connections through Hyperdrive.
Void manages the Hyperdrive configuration automatically. You only provide the connection string.
Configuration
1. Set the database
Add to your void.json:
{
"database": "pg"
}2. Add your connection string
For local development, add DATABASE_URL to .env.local:
DATABASE_URL=postgres://user:password@host:5432/mydbThis connects directly to your Postgres database during void dev.
3. Deploy
On your first deploy, the CLI will prompt for your connection string:
Your project uses PostgreSQL. Enter your connection string:
> postgres://user:password@host:5432/mydbVoid provisions a Hyperdrive configuration and stores only the config ID. Your connection string is sent directly to Cloudflare's API and is never stored by Void.
You can also set the connection string ahead of time with void db set-url.
Schema Definition
With the postgresql dialect, import schema helpers from void/schema-pg (re-exports from drizzle-orm/pg-core):
// db/schema.ts
import { pgTable, serial, text, timestamp, boolean, doublePrecision } from 'void/schema-pg';
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
email: text('email').notNull().unique(),
role: text('role').notNull().default('user'),
active: boolean('active').notNull().default(true),
createdAt: timestamp('created_at').notNull().defaultNow(),
updatedAt: timestamp('updated_at').notNull().defaultNow(),
});void gen model generates PostgreSQL-appropriate code when the dialect is set to postgresql.
Migrations
The migration workflow is the same as D1:
# Generate migration files from schema changes
void db generate
# Apply pending migrations locally
void db migrate
# Check migration status
void db statusThe main difference is that PostgreSQL supports transactional DDL. Each migration is wrapped in BEGIN and COMMIT, so a failure rolls back the whole migration instead of leaving the database half-updated.
Deploy Workflow
When you run void deploy with a PostgreSQL project:
- The app is built
- Migration files are collected from
db/migrations/ - If Hyperdrive hasn't been provisioned yet, you're prompted for the connection string
- Pending migrations run inside the deployed worker via Hyperdrive
- The new worker goes live
Updating the Connection String
To update the connection string for an existing deployment (e.g. migrating to a new database host):
void db set-urlThis prompts for the new connection string and updates the Hyperdrive configuration. The change takes effect on the next deploy.