Database Configuration
A practical overview of database setup: schema design, connection strategies, and query-layer extension practices.
MuseMVP uses Drizzle ORM with PostgreSQL for data persistence. The database layer supports both standard Node.js (Vercel, Docker) and Cloudflare Workers (through Hyperdrive connection pooling).
Download and Configure the Database
Download a database (local) or create a Neon instance (remote)
After installation and service startup, create a development database (example):
createdb musemvpOn Windows, you can use the official installer directly (with pgAdmin included); after installation, confirm the postgresql service is running.
On macOS / Linux, install via your package manager and start the service.
- Open the Neon Console and create a Project.

- In
Connection Details, copy the Pooled connection string (recommended for application runtime).
postgresql://neondb_username:npg_password@ep-xxx-bush-xxxx-pooler.ap-xxx-1.xxx.neon.tech/demo-musemvp-com?sslmode=require&channel_binding=requireConfigure the database
Create .env in the project root (you can copy from .env.local.example) with at least:
# Local development / Vercel / Docker
DATABASE_CONNECTION_STRATEGY="database_url_first"
DATABASE_URL="postgresql://<user>:<password>@<host>:5432/<database>"Then run:
pnpm drizzle:generate
pnpm drizzle:pushLocal development note
Do not use hyperdrive_first for local Node.js development; use database_url_first.
Cloudflare Worker deployment
When deploying to Cloudflare Worker, you can switch to DATABASE_CONNECTION_STRATEGY="hyperdrive_first" and configure Hyperdrive; DATABASE_URL can be used as a fallback connection.
Verify the connection:
pnpm drizzle:studioCommon Commands
pnpm drizzle:generate # Generate migrations based on schema changes
pnpm drizzle:migrate # Apply migrations to the database
pnpm drizzle:push # Push schema directly (development only)
pnpm drizzle:studio # Open Drizzle Studio GUInpm run drizzle:generate
npm run drizzle:migrate
npm run drizzle:push
npm run drizzle:studioConnection Strategy
The database client in src/backend/database/client.ts resolves connections based on runtime:
Cloudflare Worker: Prefer Hyperdrive binding (HYPERDRIVE.connectionString) for edge connection pooling.
Node.js (Vercel, Docker): Use the DATABASE_URL environment variable.
Fallback: If Hyperdrive is unavailable on Cloudflare, fall back to DATABASE_URL.
Environment Variables
DATABASE_URL is required for local development and non-Cloudflare deployments. Cloudflare Workers require Hyperdrive, with optional DATABASE_URL as fallback.
Incremental Extension Flow
Add or update tables in schema.ts.
Run pnpm drizzle:generate to generate migration files.
Run pnpm drizzle:migrate to apply migrations.
Add query functions in queries/*.
Expose behavior in src/backend/api/routes/*.
Consume via src/backend/api-client/*.
Operations Checklist
- Commit migration history to version control
- Avoid using raw SQL in route handlers - use the query layer
- Keep authentication and ownership checks in API middleware
- Use explicit indexes for growing tables (see
schema.tsexamples)